$solicitud->ajax es falso en la inserción [cerrado]

Me gustaría insertar datos en una base de datos, pero en el controlador es $request->ajax()falso. Alguien puede ayudarme? Pasé un día entero en Google, pero nada me ayudó. Estoy usando laravel 8. Usé ajax para filtrar libros. Funciona bien. Pero aquí no sé dónde está el error. Cuando uso dd($request)before si el resultado es:

Este es .jsel archivo:

$(document).ready(function () {
    $("#review-form").submit(function (e) {
        e.preventDefault();

        let reviewText = $("#reviewText").val();
        let bookID = $("#bookID").val();
        let userID = $("#userID").val();

        $.ajax({
            type: "POST",
            url: "catalog/singleBook/" + bookID,
            dataType: "json",
            data: {
                reviewText: reviewText,
                bookID: bookID,
                userID: userID,
                _token: $('meta[name="csrf-token"]').attr("content"),
            },
            success: function (response) {
                alert("X");
                console.log("X");
                $("#review-container").prepend(
                    "<div id='review'>" + response.reviewText + "</div>"
                );
                $("#review-form")[0].reset();
            },
            error: function (error) {
                console.log(error);
                console.log("RREEER");
            },
        });
    });
});

Controlador:

 public function storeReview(Request $request) {
      
      dd($request->ajax());
      
      if($request->ajax()) {
      $review = new Review;
      $review->bookID = $request->bookID;
      $review->userID = $request->userID;
      $review->reviewText = $request->reviewArea;
      $review->save();
      
      return response()->json($review);   
      }   
   }

vista:

@extends('layouts.main')

@section('title', 'Detail')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="row">
            <div class="singleBook-container">
                <div class="col-sm-2">
                    <img class="singleBook-img" src="{{ $book->img }}" alt=" {{ $book->title }}">
                </div>
                <div class="col-sm-3">
                    <ul class="singleBook-list">
                        <li>
                            <div class="title"> Nazov:</div>
                            <p>{{ $book->title }}</p>
                        </li>
                        <li>
                            <div class="title"> Autor: </div>
                            <p>{{ $book->firstname }} {{ $book->lastname }}</p>
                        </li>
                        <li>
                            <div class="title"> Rating:</div>
                            <p>{{ $book->rating }}</p>
                        </li>
                        <li>
                            <div class="title"> ISBN: </div>
                            <p>{{ $book->ISBN }}</p>
                        </li>
                    </ul>
                </div>
                <div class="col-sm-7">
                    <p>{{ $book->description }}</p>
                </div>
            </div>
        </div>

        <div class="row">
            <form id="review-form" method="Post">
                @csrf
                <div class="form-group">
                    <input type="hidden" value="{{ $book->id }}" id="bookID" name="bookID" readonly />
                    <input type="hidden" value="{{ auth()->user()->id }}" id="userID" name="userID" readonly>
                    <textarea class="form-control" name="reviewArea" id="reviewText exampleFormControlTextarea1"
                        rows="3" placeholder="Napíš recenziu.." required></textarea>
                </div>
                <button id="submitBTN" type="submit" class="btn btn-light">Odoslať</button>
            </form>
        </div>

        <div class="row">
            <h2 class="review-header">Recenzie:</h2>
            <div id="review-container">
            </div>
        </div>
    </div>
</div>
@endsection

web.php:

Route::post('catalog/singleBook/{id}', [CatalogController::class, 'storeReview'])->middleware('auth');

ingrese la descripción de la imagen aquí

Answer

De forma predeterminada, jQuery siempre establece el X-Requested-Withencabezado .

headers (default: {})
Type: PlainObject
An object of additional header key/value pairs to send along with requests using the XMLHttpRequest transport. The header X-Requested-With: XMLHttpRequest is always added, but its default XMLHttpRequest value can be changed here. Values in the headers setting can also be overwritten from within the beforeSend function. (version added: 1.5)

Si esto no sucede en su caso, intente configurar manualmente el X-Requested-Withencabezado en su resources/js/app.jsarchivo. No olvide volver a compilar sus activos.

$.ajaxSetup({
    headers: {
        "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
        "X-Requested-With": "XMLHttpRequest"
    }
});

Alternativamente, puede configurar el encabezado por solicitud ajax en lugar de globalmente.

$.ajax({
  type: "POST",
  headers: {
        "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
        "X-Requested-With": "XMLHttpRequest"
    }
    // ...
});

Advertencia (notas):

Antes de intentar configurar manualmente el X-Requested-Withencabezado al realizar solicitudes ajax con jQuery, intente verificar la solicitud en la sección del inspector de red de su navegador para confirmar que ya se agregó. En Google Chrome :

ingrese la descripción de la imagen aquí

a). Cargue la vista/página HTML donde reside su formulario.

B). Abra la consola del navegador (Ctrl + Shift + J).

C). Haga clic en la pestaña "Red". Luego haga clic en la pestaña "Obtener/XHR" que se encuentra justo debajo de la pestaña "Red".

D). Complete el formulario HTML en su página e intente enviarlo mientras mira la sección de la pestaña "Red". Debería ver una solicitud enviada en la sección de la pestaña "Red" con una URL similar a su valor de URL de Ajax.

mi). Haga clic en la solicitud en la pestaña "Red". En su caso, es posible que solo vea la "id del libro". Es decir: "1" como el nombre de la solicitud. Pero cuando pasa el cursor sobre el nombre de la solicitud, podrá ver la ruta completa. Es decir: "http://base_url_here/catalog/singleBook/1" en la sección de la pestaña "Red".

F). Una vez que haya hecho clic en/seleccionado la solicitud, seleccione la pestaña "Encabezados".

gramo). En la sección de la pestaña "Encabezados", desplácese hacia abajo hasta llegar a la parte de la lista "Encabezados de solicitud".

h). Mire la lista de encabezados en la parte "Encabezados de solicitud" y compruebe si X-Requested-With: XMLHttpRequestexiste el encabezado.

Si tiene dificultades para seguir estos pasos, intente aprender a inspeccionar la actividad de la red .

Apéndice:

Para saber por qué este encabezado es importante al realizar solicitudes ajax y cómo se relaciona con el request()->ajax()método de Laravel, consulte:

Verificación de Laravel 4 Ajax para incluir XMLHttpRequest (de Magnific Popup)

Detectar Ajax Request-Php y Frameworks

Editar:

  1. Asegúrese de que el Request $requestobjeto que está inyectando en el storeReview(...)método provenga de Illuminate\Http\Request.

  2. Esto no es obligatorio, pero es posible que desee agregar "_method" : "POST"al cuerpo de su solicitud :

$.ajax({
  type: "POST",
  data: {
  // ...
  _method: "POST" 
  },
    // ...
});
  1. Si no recibe ningún éxito con el $.ajax(...)método de jQuery , intente usar el $.post(...)método de jQuery .
$.post("catalog/singleBook/" + bookID,
    {
        reviewText: reviewText,
        bookID: bookID,
        userID: userID,
        _token: $('meta[name="csrf-token"]').attr("content"),
        _method: "POST"
    }, function (response) {
        alert("X");
        console.log("X");
        $("#review-container").prepend(
            "<div id='review'>" + response.reviewText + "</div>"
        );
        $("#review-form")[0].reset();
    },
    "json"
).fail(function () {
    console.log(error);
    console.log("RREEER");
});
  1. Creo firmemente que su URL jQuery Ajax no coincide con la web.phpdefinición de ruta de archivo compartida en su pregunta.

URL de solicitud POST de Ajax.

url: "catalog/singleBook/" + bookID,`

web.phpRuta.

Route::post('missingbook', [MissingBookController::class, 'storeBook'])->middleware('auth');

El punto final de la ruta en su web.phparchivo apunta a /missingbooksu configuración de URL del método jQuery Ajax apunta a catalog/singleBook/{id}. Es posible que desee verificar/confirmar si olvidó y compartió la web.phpdefinición de ruta de archivo incorrecta en su pregunta.

  1. Esto no está relacionado con el problema en cuestión, pero pensé que podría resultarle útil.

5a). En su marcado/vista HTML, hace referencia a la <textarea>etiqueta conid="reviewText exampleFormControlTextarea1"

   <textarea class="form-control" name="reviewArea" id="reviewText exampleFormControlTextarea1" rows="3" placeholder="Napíš recenziu.."
    required></textarea>

Sin embargo, hace referencia a ese elemento en su .jsarchivo JavaScript usando el "#reviewText"selector:

let reviewText = $("#reviewText").val();

Esos dos no coinciden en mi humilde opinión.

Le sugiero que busque en .serializeArray() de jQuery para permitirle construir el cuerpo de la solicitud automáticamente en lugar de tener que hacerlo manualmente.

Tenga en cuenta que un idvalor de atributo no debe contener espacios en blanco (espacios, tabulaciones, etc.) .

5b). En segundo lugar, envía el <textarea>valor del elemento con la clave del parámetro de solicitud como reviewTexten el cuerpo de solicitud Ajax de su jQuery:

   $.ajax({
    // ...
    data: {
        reviewText: reviewText,
        // ...
    }
    // ... 
   });

Sin embargo, en el método de su controlador, storeReview(...)intenta acceder a él usando$request->reviewArea

    public function storeReview(Request $request) { 
    // ...
    if($request->ajax()) {
        // ...
        $review->reviewText = $request->reviewArea;
        // ...
    } }

Esos dos tampoco coinciden. $request->reviewAreasin duda siempre volveremos null.

Lo arreglé... faltaba '/' en la ruta.