Laravel 5.5 ajax call 419 (ไม่ทราบสถานะ)


145

ฉันโทร ajax แต่ได้รับข้อผิดพลาดนี้:

419 (ไม่ทราบสถานะ)

ไม่รู้ว่าอะไรเป็นสาเหตุของสิ่งนี้ที่ฉันเห็นในโพสต์อื่น ๆ มันต้องทำอะไรกับโทเค็น csrf แต่ฉันไม่มีรูปแบบดังนั้นฉันไม่รู้จะแก้ไขได้อย่างไร

สายของฉัน:

$('.company-selector li > a').click(function(e) {
     e.preventDefault();

     var companyId = $(this).data("company-id");


      $.ajax({
          headers: {
          'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
          },
          url: '/fetch-company/' + companyId,
          dataType : 'json',
          type: 'POST',
          data: {},
          contentType: false,
          processData: false,
          success:function(response) {
               console.log(response);
          }
     });
  });

เส้นทางของฉัน:

Route::post('fetch-company/{companyId}', 'HomeController@fetchCompany');

วิธีการควบคุมของฉัน

/**
 * Fetches a company
 *
 * @param $companyId
 *
 * @return array
 */
public function fetchCompany($companyId)
{
    $company = Company::where('id', $companyId)->first();

    return response()->json($company);
}

เป้าหมายสูงสุดคือการแสดงบางสิ่งบางอย่างจากการตอบสนองในองค์ประกอบ HTML


4
คุณมีสิ่งนี้ไหม <meta name="csrf-token" content="{{ csrf_token() }}">
Hanlin Wang

@ HanlinWang ไม่ฉันไม่มีแบบฟอร์มมันเป็นแบบเลื่อนลง
คริส

คุณเพิ่ม {{csrf_field()}}ในแบบฟอร์มของคุณแล้วหรือยัง?
Mr. Pyramid

3
ดรอปดาวน์เป็นส่วนหนึ่งของแบบฟอร์มที่คุณต้องใช้ในการยื่นคำขอผ่านแบบฟอร์ม
Mr. Pyramid

1
หรือส่ง csrf_token ในข้อมูลของคุณเช่นนี้{'_token': {{csrf_token()}}}
Mr. Pyramid

คำตอบ:


301

ใช้สิ่งนี้ในส่วนหัว:

<meta name="csrf-token" content="{{ csrf_token() }}">

และรับโทเค็น csrf ใน ajax:

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

โปรดอ้างอิงเอกสาร Laravel csrf_token


1
ขอบคุณมันใช้งานได้สำหรับฉัน ฉันพยายามใช้วิธี 'DELETE' สำหรับการโทร ajax และมันใช้งานได้อย่างมีเสน่ห์
Salvo

4
ฉันมีการตั้งค่ารหัสที่แน่นอน แต่ฉันยังคงประสบปัญหาของ OP ในสถานการณ์ต่อไปนี้: ผู้ใช้ลงชื่อเข้าใช้ แต่ไซต์ยังคงไม่ได้ใช้งานเป็นเวลานาน (ตัวอย่างเช่นคอมพิวเตอร์เข้าสู่โหมดสลีปเมื่อเปิดเบราว์เซอร์) ในกรณีนี้เมื่อผู้ใช้กลับไปที่คอมพิวเตอร์และลองโทร AJAX ข้อผิดพลาดนี้จะเกิดขึ้น หลังจากโหลดซ้ำทุกอย่างกลับสู่ปกติ ใครมีวิธีแก้ปัญหานี้?
jovan

@ โจแวนมีสองวิธีที่คุณสามารถทำได้อย่างง่ายดาย ลองดูที่ห้องสมุด jQuery เหล่านี้น่ากลัวhttps://www.jqueryscript.net/other/Session-Timeout-Alert-Plugin-With-jQuery-userTimeout.html https://github.com/kidh0/jquery.idle ประการที่สองในคำขอ ajax ของคุณตรวจสอบว่ามันส่งคืนรหัสข้อผิดพลาด 419 แล้วเปลี่ยนเส้นทาง
riliwanrabo

@ โจแวนฉันก็ต้องดิ้นรนกับเรื่องนี้และแม้กระทั่งปิดเบราว์เซอร์ ฯลฯ ก็จะไม่แก้ไขปัญหา ฉันจัดการเพื่อค้นหาวิธีการแก้ไขแม้ว่าและโดยการใส่รหัส 'ajaxsetup ()' ดังกล่าวข้างต้นภายในการโพสต์ของฉันโทร () - โทเค็น csrf ถูกตั้งค่าอย่างถูกต้องและทุกอย่างเริ่มทำงานอย่างไม่มีที่ติ
SupaMonkey

2
แต่ทำไม419 Unknown status? ทำไม419 Invalid CSRF tokenการตอบกลับที่มีประโยชน์และมีประโยชน์ มันมาจากไหน? ทำไม? อื่น ๆ
Rudie

26

อีกวิธีในการแก้ไขปัญหานี้คือการใช้_tokenฟิลด์ในข้อมูล ajax และตั้งค่าเป็น{{csrf_token()}}เบลด นี่คือรหัสการทำงานที่ฉันเพิ่งลองใช้เมื่อสิ้นสุด

$.ajax({
    type: "POST",
    url: '/your_url',
    data: { somefield: "Some field value", _token: '{{csrf_token()}}' },
    success: function (data) {
       console.log(data);
    },
    error: function (data, textStatus, errorThrown) {
        console.log(data);

    },
});

ส่วนหัว: {'X-CSRF-TOKEN': $ ('meta [name = "csrf-token"]'). attr ('เนื้อหา')},
Kamlesh

12

นี่คล้ายกับคำตอบของ Kannan อย่างไรก็ตามวิธีนี้จะช่วยแก้ปัญหาที่ไม่ควรส่งโทเค็นไปยังไซต์ข้ามโดเมน สิ่งนี้จะตั้งค่าส่วนหัวหากเป็นคำขอในท้องถิ่น

HTML:

<meta name="csrf-token" content="{{ csrf_token() }}">

JS:

$.ajaxSetup({
    beforeSend: function(xhr, type) {
        if (!type.crossDomain) {
            xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'));
        }
    },
});

การตั้งค่าส่วนหัวปกติใช้งานได้สำหรับฉันซักพัก แต่สุ่มเริ่มมีปัญหาหลังจากใช้งานได้หลายเดือน ฉันไม่แน่ใจว่าทำไมมันเริ่มมีปัญหาจากที่ใด แต่วิธีนี้ใช้งานได้ดีและแก้ไขปัญหาสำหรับฉัน
Frank A.

7

ใช้สิ่งนี้ในหน้าของคุณ

<meta name="csrf-token" content="{{ csrf_token() }}">

และในอาแจ็กซ์ของคุณใช้มันในข้อมูล:

_token: '{!! csrf_token() !!}',

นั่นคือ:

$.ajax({
          url: '/fetch-company/' + companyId,
          dataType : 'json',
          type: 'POST',
          data: {
                   _token: '{!! csrf_token() !!}',
                 },
          contentType: false,
          processData: false,
          success:function(response) {
               console.log(response);
          }
     });

ขอบคุณ


7

อาจเป็นไปได้ที่โดเมนเซสชันของคุณไม่ตรงกับ URL แอปและ / หรือโฮสต์ที่ใช้ในการเข้าถึงแอปพลิเคชัน

1. ) ตรวจสอบไฟล์. env ของคุณ:

SESSION_DOMAIN=example.com
APP_URL=example.com

2. ) ตรวจสอบ config / session.php

ตรวจสอบค่าเพื่อให้แน่ใจว่าถูกต้อง


1
นี่เป็นทางออกที่ถูกต้องสำหรับฉัน น่าผิดหวังมากรหัส HTTP 419 ไม่ตรงกับข้อมูลจำเพาะ HTTP และอาจมีความหมายมากมาย
Cobolt

5

หากคุณทำตามคำแนะนำข้างต้นแล้วและยังมีปัญหาอยู่

ตรวจสอบให้แน่ใจว่าตัวแปร env:

SESSION_SECURE_COOKIE

ตั้งเป็นfalse หากคุณไม่มีใบรับรอง SSL เช่นเดียวกับในเครื่อง


4

ในกรณีของฉันฉันลืมที่จะเพิ่มอินพุต csrf_token ไปยังแบบฟอร์มที่ส่ง ดังนั้นฉันทำ HTML นี้:

<form class="form-material" id="myform">
...
<input type="file" name="l_img" id="l_img">
<input type="hidden" id="_token" value="{{ csrf_token() }}">
..
</form>

JS:

//setting containers
        var _token = $('input#_token').val();
        var l_img = $('input#l_img').val();
        var formData = new FormData();
        formData.append("_token", _token);
        formData.append("l_img", $('#l_img')[0].files[0]);

        if(!l_img) {
            //do error if no image uploaded
            return false;
        }
        else
        {
            $.ajax({
                type: "POST",
                url: "/my_url",
                contentType: false,
                processData: false,
                dataType: "json",
                data : formData,
                beforeSend: function()
                {
                    //do before send
                },
                success: function(data)
                {
                    //do success
                },
                error: function(jqXhr, textStatus, errorThrown) //jqXHR, textStatus, errorThrown
                {
                    if( jqXhr.status === "422" ) {
                        //do error
                    } else {
                        //do error
                    }
                }
            });
        }
        return false; //not to post the form physically

1
นี่<input type="hidden" id="_token" value="{{ csrf_token() }}">เป็นสิ่งจำเป็นแม้ว่าเราจะส่ง whitouth ajax มิฉะนั้นฉันก็มีข้อผิดพลาด 419 แปลก
Sr.PEDRO

3

แม้ว่าคุณจะมีcsrf_tokenแต่ถ้าคุณรับรองความถูกต้องของการกระทำของตัวควบคุมโดยใช้ Laravel Policiesคุณสามารถมีการตอบสนอง 419 เช่นกัน ในกรณีนี้คุณควรเพิ่มฟังก์ชั่นนโยบายที่จำเป็นในPolicyชั้นเรียนของคุณ


3

หากคุณกำลังโหลด. js จากไฟล์คุณต้องตั้งค่าตัวแปรด้วย csrf_token ในไฟล์ "main" .blade.php ของคุณซึ่งคุณกำลังนำเข้า. js และใช้ตัวแปรในการโทร ajax ของคุณ

index.blade.php

...
...
<script src="{{ asset('js/anotherfile.js') }}"></script>
<script type="text/javascript">
        var token = '{{ csrf_token() }}';
</script>

anotherfile.js

$.ajax({
    url: 'yourUrl',
    type: 'POST',
    data: {
        '_token': token
    },
    dataType: "json",
    beforeSend:function(){
        //do stuff
    },
    success: function(data) {
        //do stuff
    },
    error: function(data) {
        //do stuff
    },
    complete: function(){
        //do stuff
    }
});

1

some refs =>

...
<head>
    // CSRF for all ajax call
    <meta name="csrf-token" content="{{ csrf_token() }}" />
</head>
 ...
 ...
<script>
    // CSRF for all ajax call
    $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': jQuery('meta[name="csrf-token"]').attr('content') } });
</script>
...

1

เพียงแค่เรียงลำดับข้อมูลในแบบฟอร์มและแก้ไขปัญหาของคุณ

data: $('#form_id').serialize(),

1

คุณต้องรับโทเค็น csrf ..

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

หลังจากทำปัญหาเดียวกันเพิ่มขึ้นเพียงเพิ่มเมตาแท็กนี้< meta name="csrf-token" content="{{ csrf_token() }}" >

หลังจากนี้ยังเกิดข้อผิดพลาดคุณสามารถตรวจสอบข้อผิดพลาด Ajax จากนั้นตรวจสอบข้อผิดพลาด Ajax ด้วย

$.ajax({
    url: 'some_unknown_page.html',
    success: function (response) {
        $('#post').html(response.responseText);
    },
    error: function (jqXHR, exception) {
        var msg = '';
        if (jqXHR.status === 0) {
            msg = 'Not connect.\n Verify Network.';
        } else if (jqXHR.status == 404) {
            msg = 'Requested page not found. [404]';
        } else if (jqXHR.status == 500) {
            msg = 'Internal Server Error [500].';
        } else if (exception === 'parsererror') {
            msg = 'Requested JSON parse failed.';
        } else if (exception === 'timeout') {
            msg = 'Time out error.';
        } else if (exception === 'abort') {
            msg = 'Ajax request aborted.';
        } else {
            msg = 'Uncaught Error.\n' + jqXHR.responseText;
        }
        $('#post').html(msg);
    },
});

1
formData = new FormData();
formData.append('_token', "{{csrf_token()}}");
formData.append('file', blobInfo.blob(), blobInfo.filename());
xhr.send(formData);

ขอขอบคุณสำหรับข้อมูลโค้ดนี้ซึ่งอาจให้ความช่วยเหลือแบบ จำกัด และทันที คำอธิบายที่เหมาะสมมากจะเพิ่มมูลค่าในระยะยาวด้วยการแสดงเหตุผลนี้เป็นทางออกที่ดีในการแก้ไขปัญหาและจะทำให้มันมีประโยชน์มากขึ้นให้กับผู้อ่านในอนาคตกับอื่น ๆ คำถามที่คล้ายกัน โปรดแก้ไขคำตอบของคุณเพื่อเพิ่มคำอธิบายรวมถึงข้อสมมติที่คุณได้ทำไว้
CertainPerformance

1

2019 Laravel Update ไม่คิดว่าฉันจะโพสต์สิ่งนี้ แต่สำหรับนักพัฒนาอย่างฉันที่ใช้เบราว์เซอร์เรียก API บน Laravel 5.8 ขึ้นไป คุณต้องส่งโทเค็นของคุณผ่านพารามิเตอร์ส่วนหัว

var _token = "{{ csrf_token }}";
fetch("{{url('add/new/comment')}}", {
                method: 'POST',
                headers: {
                    'X-CSRF-TOKEN': _token,
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(name, email, message, article_id)
            }).then(r => {
                return r.json();
            }).then(results => {}).catch(err => console.log(err));

1

ฉัน SESSION_SECURE_COOKIEตั้งค่าเป็นจริงเพื่อให้สภาพแวดล้อม dev ของฉันไม่ทำงานเมื่อลงชื่อเข้าใช้ดังนั้นฉันจึงเพิ่มSESSION_SECURE_COOKIE=false ไฟล์ dev .env ของฉันและทำงานได้ดีความผิดพลาดของฉันคือการเปลี่ยนไฟล์ session.php แทนการเพิ่มตัวแปรลงในไฟล์. env


0

ข้อผิดพลาดนี้จะเกิดขึ้นหากคุณลืมที่จะรวมสิ่งนี้ไว้ในคำขอส่ง ajax (POST) ของคุณ contentType: false, processData: false,


0

พบข้อผิดพลาดนี้แม้ว่าฉันจะส่งโทเค็น csrf แล้ว ปรากฎว่าไม่มีพื้นที่เหลือบนเซิร์ฟเวอร์


0

วิธีนี้ใช้งานได้ดีสำหรับกรณีที่คุณไม่ต้องการใช้แบบฟอร์ม

ใช้สิ่งนี้ในส่วนหัว:

<meta name="csrf-token" content="{{ csrf_token() }}">

และสิ่งนี้ในรหัส JavaScript ของคุณ:

$.ajaxSetup({
        headers: {
        'X-CSRF-TOKEN': '<?php echo csrf_token() ?>'
        }
    });

0

วิธีง่ายๆในการแก้ไขสถานะที่ไม่รู้จัก 419 บนคอนโซลของคุณคือการวางสคริปต์นี้ไว้ในฟอร์มของคุณ {{csrf_field ()}}


0

สิ่งนี้ใช้ได้กับฉัน:

$.ajaxSetup({
  headers: {
    'X-CSRF-TOKEN': "{{ csrf_token() }}"
  }
});

หลังจากตั้งค่าการโทร AJAX ปกติ ตัวอย่าง:

    $.ajax({
       type:'POST',
       url:'custom_url',

       data:{name: "some name", password: "pass", email: "test@test.com"},

       success:function(response){

          // Log response
          console.log(response);

       }

    });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.