Laravel Axios 使用 Vue 失败,状态码 419

Posted

技术标签:

【中文标题】Laravel Axios 使用 Vue 失败,状态码 419【英文标题】:Laravel Axios Failed with status code 419 using Vue 【发布时间】:2018-05-03 15:53:02 【问题描述】:

概念:我有一个允许用户发布问题的应用程序...当用户单击“询问”按钮时,我尝试使用 Vue.js 和 Axios 提交问题。

问题: 70% 的时间问题正确提交,但有 30% 的时间失败并返回“加载资源失败:服务器响应状态为 419(未知状态)"

我的 Vue 组件

<template>
    <div id = "main_question_box" class = "tab-pane fade">
        <div class="panel-body posting-field-box">        
            <textarea name="feed_body" class="summernote posting-field form-control"></textarea>
            <button class = "example-btn btn btn-xs btn-default pull-right">View Question Examples</button>                                    
        </div>

        <div class="panel-footer">
            <ul class="list-inline pull-right">
                <li>
                    <button @click = "sendPost" class="feed-post-btn btn btn-submit btn-sm btn-success pl-l pr-l">
                        <span>Ask</span>
                        <i class="fa fa-paper-plane pl-sm"></i>
                    </button>
                </li>
            </ul>

            <div class="clearfix"></div>
        </div>
    </div>
</template>

<script>

    axios.defaults.headers.common['X-CSRF-TOKEN'] = document.querySelector('meta[name="csrf-token"]').getAttribute('content')

    export default 
        props:['timelineId'],
        data()
            return 
                feed_body: '',
                timeline_id: this.timelineId,
                type: 'Question',
                post_ready: false
             
        , 
        methods: 
            sendPost: function () 
                this.compilePost(this);
                if(this.post_ready)
                    var self = this;
                    self.startLoader();
                    axios.post('/timeline',
                    
                        feed_body: this.feed_body,
                        timeline_id: this.timeline_id,
                        feed_type: this.type

                    ).then(response =>
                        this.feed_body = '';
                        this.post_ready = false;
                        $('#main_question_box .summernote').summernote('code', '');
                        this.$emit('newFeedSent', response.data);
                    );
                
            ,
            startLoader: function()
                $('.feed-post-btn').addClass('btn-default').removeClass('btn-success').prop('disabled', true).find('span').hide();
                $('.feed-post-btn').find('i').attr('class', 'fa fa-cog fa-spin fa-2x fa-fw');       
            ,
            compilePost: function(instance) 
                var editor = $('#main_question_box .summernote');
                var isEmpty = $(editor).summernote('isEmpty');
                if(!isEmpty)
                    instance.feed_body = $(editor).summernote('code');
                    instance.post_ready = true;
                else
                    instance.post_ready = false;
                
            
        
    

</script>

我的 Web.php

Route::post('/timeline', 'FeedController@storeFeed');

我的控制器

public function storeFeed(Request $request)


    if($request->feed_type == 'Debate')
        $this->validate(request(), [
            'feed_subject' => 'required',
            'feed_body' => 'required',
        ]);

        $publishedFeed = Auth::user()->publishDebate($request);

    elseif($request->feed_type == 'Question')
        $this->validate(request(), [
            'feed_body' => 'required',
        ]);

        $publishedFeed = Auth::user()->publishQuestion($request);

    else
        $this->validate(request(), [
            'feed_body' => 'required',
        ]);

        $publishedFeed = Auth::user()->publishPost($request);
    


    return $publishedFeed->id;


我的 HTML 头

<!DOCTYPE html>
<html lang=" app()->getLocale() ">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="login-status" content=" Auth::check() ">

    <!-- CSRF Token -->
    <meta name="csrf-token" content=" csrf_token() ">

我的资源\资产\js\Bootstrap.js

    window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

/**
 * Next we will register the CSRF Token as a common header with Axios so that
 * all outgoing HTTP requests automatically have it attached. This is just
 * a simple convenience so we don't have to attach every token manually.
 */

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) 
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
 else 
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');

【问题讨论】:

这可能不是 419 错误,而是您在 419 之前遇到的 500 错误。单击您的网络选项卡并发布 500 错误。未知状态是因为 500 错误。 如果根本问题实际上 419 而不是之前的 500,正如@whoacowboy 所建议的:Laravel 抛出 419s 主要来自 csrf 令牌问题和 api 路由。看看this question、this question 或this forum post 是否对你有用。 你能把 chrome 控制台的网络面板说的内容贴出来吗? 我看不到您的路由“/timeline”是如何受到保护的,因为您在显示的代码中没有使用任何身份验证中间件 【参考方案1】:

我可以重现这个问题。

    正常使用 Vuejs/Laravel 应用程序。

    在控制器中使用 \Session::flush() 刷新页面 public function getProduct(Request $request) \Session::flush(); return view('product');

    从客户端发出 put/post 请求 ->请求失败,状态码为 419

    这可能意味着在开发中您的会话已过期,因此您可以尝试将会话生命周期设置为更高的数字,看看是否可以解决问题。

【讨论】:

以上是关于Laravel Axios 使用 Vue 失败,状态码 419的主要内容,如果未能解决你的问题,请参考以下文章

Axios 中的 Cors OPTIONS 方法在 Laravel 和 Nginx 中失败

Vue.js - 当标头中使用 multipart/form-data 时,axios 中的文件上传验证失败

如何在 Vue 和 Laravel 中使用 axios 上传图像文件和数据对象?

Laravel + Vue.js (axios) 使用网络路由 - 未经身份验证

Laravel Vue Axios 未定义

Axios CORS/Preflight 因 Laravel 5.4 API 调用而失败