Ajax定期工作。有时POST请求返回错误419

时间:2019-05-02 05:58:23

标签: javascript ajax laravel

在Laravel的帮助下,我创建了一个多语言的网站。当我使用Ajax切换语言时,有时会出现错误。 Javascript代码:

$(document).ready(function(){
    $("#LanguageSwitcher").change(function(){
        var locale = $(this).val();
        var _token = $('meta[name="csrf-token"]').attr('content');

        $.ajax({
            url: "/language",
            type: 'POST',
            data: {locale: locale, _token: _token},
            datatype: 'json',
            beforeSend: function () {
                console.log('before send - ' + locale);
            },
            success: function (data) {
                console.log('success');
            },
            error: function (error) {
                console.log(error);
            },
            complete: function (data) {
                    window.location.reload(true);
            }
        });
    });
});

web.php:

Route::post('/language/', array(
    'before' => 'csrf', 
    'uses' => 'LanguageController@changeLanguage' 
));

控制器:

class LanguageController extends Controller
{
    public function changeLanguage(Request $request){
        if ($request->ajax()) {
            $request->session()->put('locale', $request->locale);
        }
    }
}

layout.blade.php:

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

        <select id="LanguageSwitcher" class="btn btn-outline-danger">
                <option>...code...</option>
                <option>...code...</option>
                <option>...code...</option>
        </select>

当我通过另一个浏览器时,一切正常。如果我进入隐身模式,它也可以使用。这可能是由于我登录到管理面板吗?

4 个答案:

答案 0 :(得分:0)

像这样放置您的ajax呼叫。

req = $.ajax({
    type: "POST",
    url: "/search",
    data: {
        "locale": locale,
        "_token": "{{ csrf_token() }}",
    },
    dataType: "json",
    success: function(msg){

    }
});

答案 1 :(得分:0)

我看到了您的代码。 您在请求中传递csrf令牌。您面临的问题是,您的csrf令牌没有被更新。

比方说,您不会重新加载页面,在您第一次进入页面时,laravel会给您提供您通过meta提供给ajax的csrf令牌。

但是在后端(laravel端)上经过了一段时间。您的csrf令牌已更新,但您尚未在客户端更新过。要获取更新的令牌,您需要重新加载页面。

因此,对于此问题,您需要检查何时获得错误状态419,向laravel请求新的csrf令牌(通过创建新路由,从laravel帮助器csrf_token()返回csrf令牌)并更新到您的文件。并根据您的请求将该令牌发送回laravel。

用于将令牌更新到您的页面

document.querySelector('meta[name=csrf-token]').setAttribute('content', res.data.csrf);

或者您可以通过重新加载页面来刷新令牌

答案 2 :(得分:0)

在刀片视图的meta标签中添加csrf令牌

String buffer = new String();
buffer=buffer.concat("aa");
String returned = buffer;
buffer=buffer.concat("vvvv"); // doesn't affect the returned instance
return returned;

在您的Ajax函数中:

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

答案 3 :(得分:0)

我找到了答案,但仍然不明白它是如何工作的,请解释谁知道。 App \ Exceptions \ Handler.php

public function render($request, Exception $exception)
    {
        // code for updating token when session is expired
        if ($exception instanceof \Illuminate\Session\TokenMismatchException) {            
            return Redirect::back()->withErrors(['session' => 'Sorry, your session seems to have expired. Try Again']);
        }

        return parent::render($request, $exception);
    }