【问题标题】:POST Error in Ajax with Laravel, Vue-2, vue-composer使用 Laravel、Vue-2、vue-composer 在 Ajax 中发布错误
【发布时间】:2017-07-25 22:38:22
【问题描述】:

我正在使用 Laravel、Vagrant、Vue 2(使用 vue-resource)在 OS X 中进行一个学习项目,并在选择要上传的视频文件后遇到一些错误:

控制台错误 #1:

    POST http://view.app:8000/videos 500 (Internal Server Error)
    (anonymous) @ vue-resource.common.js?2f13:1068
    PromiseObj @ vue-resource.common.js?2f13:198
    xhrClient @ vue-resource.common.js?2f13:1014
    sendRequest @ vue-resource.common.js?2f13:1174
    exec @ vue-resource.common.js?2f13:1129
    next @ vue-resource.common.js?2f13:1155
    before @ vue-resource.common.js?2f13:970
    exec @ vue-resource.common.js?2f13:1129
    next @ vue-resource.common.js?2f13:1155
    method @ vue-resource.common.js?2f13:984
    exec @ vue-resource.common.js?2f13:1129
    next @ vue-resource.common.js?2f13:1155
    body @ vue-resource.common.js?2f13:849
    exec @ vue-resource.common.js?2f13:1129
    next @ vue-resource.common.js?2f13:1155
    jsonp @ vue-resource.common.js?2f13:957
    exec @ vue-resource.common.js?2f13:1129
    next @ vue-resource.common.js?2f13:1155
    header @ vue-resource.common.js?2f13:1004
    exec @ vue-resource.common.js?2f13:1129
    next @ vue-resource.common.js?2f13:1155
    cors @ vue-resource.common.js?2f13:826
    exec @ vue-resource.common.js?2f13:1129
    (anonymous) @ vue-resource.common.js?2f13:1158
    PromiseObj @ vue-resource.common.js?2f13:198
    Client @ vue-resource.common.js?2f13:1122
    Http @ vue-resource.common.js?2f13:1359
    Http.(anonymous function) @ vue-resource.common.js?2f13:1397
    store @ VideoUpload.vue?1c05:48
    boundFn @ vue.common.js?e881:127
    fileInputChange @ VideoUpload.vue?1c05:40
    boundFn @ vue.common.js?e881:126
    invoker @ vue.common.js?e881:1637

控制台错误 #2:

    upload:1 Uncaught (in promise) 
    Response
    body: "<!DOCTYPE html>↵<html>↵    <head>↵        <meta charset="UTF-8" />↵        <meta name="robots" content="noindex,nofollow" />↵        <style>↵            /* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */↵            html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}↵↵            html { background: #eee; padding: 10px }↵            img { border: 0; }↵            #sf-resetcontent { width:970px; margin:0 auto; }↵                        .sf-reset { font: 11px Verdana, Arial, sans-serif; color: #333 }↵            .sf-reset .clear { clear:both; height:0; font-size:0; line-height:0; }↵            .sf-reset .clear_fix:after { display:block; height:0; clear:both; visibility:hidden; }↵            .sf-reset .clear_fix { display:inline-block; }↵            .sf-reset * html .clear_fix { height:1%; }↵            .sf-reset .clear_fix { display:block; }↵            .sf-reset, .sf-reset .block { margin: auto }↵            .sf-reset abbr { border-bottom: 1px dotted #000; cursor: help; }↵            .sf-reset p { font-size:14px; line-height:20px; color:#868686; padding-bottom:20px }↵            .sf-reset strong { font-weight:bold; }↵            .sf-reset a { color:#6c6159; cursor: default; }↵            .sf-reset a img { border:none; }↵            .sf-reset a:hover { text-decoration:underline; }↵            .sf-reset em { font-style:italic; }↵            .sf-reset h1, .sf-reset h2 { font: 20px Georgia, "Times New Roman", Times, serif }↵            .sf-reset .exception_counter { background-color: #fff; color: #333; padding: 6px; float: left; margin-right: 10px; float: left; display: block; }↵            .sf-reset .exception_title { margin-left: 3em; margin-bottom: 0.7em; display: block; }↵            .sf-reset .exception_message { margin-left: 3em; display: block; }↵            .sf-reset .traces li { font-size:12px; padding: 2px 4px; list-style-type:decimal; margin-left:20px; }↵            .sf-reset .block { background-color:#FFFFFF; padding:10px 28px; margin-bottom:20px;↵                border-bottom-right-radius: 16px;↵                border-bottom-left-radius: 16px;↵                border-bottom:1px solid #ccc;↵                border-right:1px solid #ccc;↵                border-left:1px solid #ccc;↵                word-wrap: break-word;↵            }↵            .sf-reset .block_exception { background-color:#ddd; color: #333; padding:20px;↵                border-top-left-radius: 16px;↵                border-top-right-radius: 16px;↵                border-top:1px solid #ccc;↵                border-right:1px solid #ccc;↵                border-left:1px solid #ccc;↵                overflow: hidden;↵                word-wrap: break-word;↵            }↵            .sf-reset a { background:none; color:#868686; text-decoration:none; }↵            .sf-reset a:hover { background:none; color:#313131; text-decoration:underline; }↵            .sf-reset ol { padding: 10px 0; }↵            .sf-reset h1 { background-color:#FFFFFF; padding: 15px 28px; margin-bottom: 20px;↵                border-radius: 10px;↵                border: 1px solid #ccc;↵            }↵        </style>↵    </head>↵    <body ondblclick="var t = event.target; if (t.title && !t.href) { var f = t.innerHTML; t.innerHTML = t.title; t.title = f; }">↵                    <div id="sf-resetcontent" class="sf-reset">↵                <h1>Whoops, looks like something went wrong.</h1>↵                                        <h2 class="block_exception clear_fix">↵                            <span class="exception_counter">1/1</span>↵                            <span class="exception_title"><abbr title="Illuminate\Session\TokenMismatchException">TokenMismatchException</abbr> in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php line 68">VerifyCsrfToken.php line 68</a>:</span>↵                            <span class="exception_message"></span>↵                        </h2>↵                        <div class="block">↵                            <ol class="traces list_exception">↵       <li> in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php line 68">VerifyCsrfToken.php line 68</a></li>↵       <li>at <abbr title="Illuminate\Founda…ate\Foundation\Http\Middleware\TransformsRequest">TransformsRequest</abbr>->handle(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>), <em>object</em>(<abbr title="Closure">Closure</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php line 148">Pipeline.php line 148</a></li>↵       <li>at <abbr title="Illuminate\Pipeline\Pipeline">Pipeline</abbr>->Illuminate\Pipeline\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php line 53">Pipeline.php line 53</a></li>↵       <li>at <abbr title="Illuminate\Routing\Pipeline">Pipeline</abbr>->Illuminate\Routing\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php line 30">TransformsRequest.php line 30</a></li>↵       <li>at <abbr title="Illuminate\Foundation\Http\Middleware\TransformsRequest">TransformsRequest</abbr>->handle(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>), <em>object</em>(<abbr title="Closure">Closure</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php line 148">Pipeline.php line 148</a></li>↵       <li>at <abbr title="Illuminate\Pipeline\Pipeline">Pipeline</abbr>->Illuminate\Pipeline\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php line 53">Pipeline.php line 53</a></li>↵       <li>at <abbr title="Illuminate\Routing\Pipeline">Pipeline</abbr>->Illuminate\Routing\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php line 27">ValidatePostSize.php line 27</a></li>↵       <li>at <abbr title="Illuminate\Foundation\Http\Middleware\ValidatePostSize">ValidatePostSize</abbr>->handle(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>), <em>object</em>(<abbr title="Closure">Closure</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php line 148">Pipeline.php line 148</a></li>↵       <li>at <abbr title="Illuminate\Pipeline\Pipeline">Pipeline</abbr>->Illuminate\Pipeline\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php line 53">Pipeline.php line 53</a></li>↵       <li>at <abbr title="Illuminate\Routing\Pipeline">Pipeline</abbr>->Illuminate\Routing\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php line 46">CheckForMaintenanceMode.php line 46</a></li>↵       <li>at <abbr title="Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode">CheckForMaintenanceMode</abbr>->handle(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>), <em>object</em>(<abbr title="Closure">Closure</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php line 148">Pipeline.php line 148</a></li>↵       <li>at <abbr title="Illuminate\Pipeline\Pipeline">Pipeline</abbr>->Illuminate\Pipeline\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php line 53">Pipeline.php line 53</a></li>↵       <li>at <abbr title="Illuminate\Routing\Pipeline">Pipeline</abbr>->Illuminate\Routing\{closure}(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php line 102">Pipeline.php line 102</a></li>↵       <li>at <abbr title="Illuminate\Pipeline\Pipeline">Pipeline</abbr>->then(<em>object</em>(<abbr title="Closure">Closure</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php line 149">Kernel.php line 149</a></li>↵       <li>at <abbr title="Illuminate\Foundation\Http\Kernel">Kernel</abbr>->sendRequestThroughRouter(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php line 116">Kernel.php line 116</a></li>↵       <li>at <abbr title="Illuminate\Foundation\Http\Kernel">Kernel</abbr>->handle(<em>object</em>(<abbr title="Illuminate\Http\Request">Request</abbr>)) in <a title="/home/vagrant/www/view/public/index.php line 53">index.php line 53</a></li>↵    </ol>↵</div>↵↵            </div>↵    </body>↵</html>"
    bodyBlob: Blob
    bodyText: Promise
    Objdata: (...)
    headers: Headers
    ok: false
    status: 500
    statusText: "Internal Server Error"
    url: "/videos"
    get data: get()
    set data: set(body)        
    __proto__: Object

同样出现 XHR 错误:

    TokenMismatchException in VerifyCsrfToken.php line 68:
    in VerifyCsrfToken.php line 68
    at VerifyCsrfToken->handle(object(Request), object(Closure)) 
    in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) 
    in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) 
    in ShareErrorsFromSession.php line 49
    at ShareErrorsFromSession->handle(object(Request), object(Closure))                    in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in StartSession.php line 64
    at StartSession->handle(object(Request), object(Closure)) in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in AddQueuedCookiesToResponse.php line 37
    at AddQueuedCookiesToResponse->handle(object(Request), object(Closure)) in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in EncryptCookies.php line 59
    at EncryptCookies->handle(object(Request), object(Closure)) in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 102
    at Pipeline->then(object(Closure)) in Router.php line 561
    at Router->runRouteWithinStack(object(Route), object(Request)) in Router.php line 520
    at Router->dispatchToRoute(object(Request)) in Router.php line 498
    at Router->dispatch(object(Request)) in Kernel.php line 174
    at Kernel->Illuminate\Foundation\Http\{closure}(object(Request)) in Pipeline.php line 30
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in TransformsRequest.php line 30
    at TransformsRequest->handle(object(Request), object(Closure)) in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in TransformsRequest.php line 30
    at TransformsRequest->handle(object(Request), object(Closure)) in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in ValidatePostSize.php line 27
    at ValidatePostSize->handle(object(Request), object(Closure)) in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in CheckForMaintenanceMode.php line 46
    at CheckForMaintenanceMode->handle(object(Request), object(Closure)) in Pipeline.php line 148
    at Pipeline->Illuminate\Pipeline\{closure}(object(Request)) in Pipeline.php line 53
    at Pipeline->Illuminate\Routing\{closure}(object(Request)) in Pipeline.php line 102
    at Pipeline->then(object(Closure)) in Kernel.php line 149
    at Kernel->sendRequestThroughRouter(object(Request)) in Kernel.php line 116
    at Kernel->handle(object(Request)) in index.php line 53

那个 CSRF 错误让我首先想到我应该从那里开始。我遇到了这个 Laravel 文档 (X-CSRF-TOKEN),但如果这是问题所在,我不确定该放在哪里。

我也遇到了很多关于 vue-resource 以及 Axios 如何成为更好选择的讨论。如果这不是 CSRF 问题,是否值得从 vue-resource 切换到 Axios?

最后,也许我只需要在 Laravel 中重新创建项目,看看是不是这样。这是可取的吗?对不起,初学者的问题,但我很感激任何帮助。

视频上传.vue

      <template>
            <div class="container">
                <div class="row">
                    <div class="col-md-8 col-md-offset-2">
                        <div class="panel panel-default">
                            <div class="panel-heading">Example</div>

                            <div class="panel-body">
                                <input type="file" name="video" id="video" @change="fileInputChange" v-if="!uploading">

                                        <div id="video-form" v-if="uploading && !failed">
                                    Form
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </template>

        <script>
            export default {
                data() {
                    return {
                        uploading: false,
                        uploadingComplete: false,
                        failed: false,
                        title: 'Untitled',
                        description: null,
                        visibility: 'private'
                    }
                },
                methods: {
                    fileInputChange() {
                        this.uploading = true;
                        this.failed = false;

                        this.file = document.getElementById('video').files[0];

                        this.store().then(() => {
                            //upload the video
                        })

                        //store the metadata
                        //upload the video
                    },
                    store() {
                        return this.$http.post('/videos', {
                           title: this.title,
                           description: this.description,
                           visibility: this.visibility, 
                           extension: this.file.name.split('.').pop() 
                        }).then((response) => {
                            console.log(response.json());
                        });
                    }
                },

                mounted() {
                    console.log('Component mounted.')
                }
            }
        </script>

package.json

{
  "private": true,
  "scripts": {
    "prod": "gulp --production",
    "dev": "gulp watch"
  },
  "devDependencies": {
    "bootstrap-sass": "^3.3.7",
    "gulp": "^3.9.1",
    "jquery": "^3.1.0",
    "laravel-elixir": "^6.0.0-9",
    "laravel-elixir-vue-2": "^0.3.0",
    "laravel-elixir-webpack-official": "^1.0.2",
    "lodash": "^4.14.0",
    "video.js": "^5.11.6",
    "vue": "^2.2.1",
    "vue-resource": "^1.2.1"
  }
}

我一定是做错了什么。我看到源代码中引用了 csrf-token。添加来源:

<!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- CSRF Token -->
        <meta name="csrf-token" content="8WH63seUHqELXf6NFMv5FY6OYHbvYZoVVrBeoQAR">

        <title>View</title>

        <!-- Styles -->
        <link href="http://view.app:8000/css/app.css" rel="stylesheet">

        <!-- Scripts -->
        <script>
            window.Laravel = {"csrfToken":"8WH63seUHqELXf6NFMv5FY6OYHbvYZoVVrBeoQAR"};
        </script>
    </head>
    <body>
            <div id="app">
        <nav class="navbar navbar-default navbar-static-top">
            <div class="container">
                <div class="navbar-header">

                    <!-- Collapsed Hamburger -->
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#app-navbar-collapse">
                        <span class="sr-only">Toggle Navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>

                    <!-- Branding Image -->
                    <a class="navbar-brand" href="http://view.app:8000">
                        View
                    </a>
                </div>

                <div class="collapse navbar-collapse" id="app-navbar-collapse">
                    <!-- Left Side Of Navbar -->
                    <ul class="nav navbar-nav">
                        &nbsp;
                    </ul>

                    <!-- Right Side Of Navbar -->
                    <ul class="nav navbar-nav navbar-right">
                        <!-- Authentication Links -->
                                                <li><a href="http://view.app:8000/upload">Upload</a></li>
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
                                    Stephen <span class="caret"></span>
                                </a>

                                <ul class="dropdown-menu" role="menu">
                                    <li>
                                        <a href="http://view.app:8000/channel/StephenChannel">Your channel</a>
                                        <a href="http://view.app:8000/channel/StephenChannel/edit">Channel settings</a>

                                        <a href="http://view.app:8000/logout"
                                            onclick="event.preventDefault();
                                                     document.getElementById('logout-form').submit();">
                                            Logout
                                        </a>

                                        <form id="logout-form" action="http://view.app:8000/logout" method="POST" style="display: none;">
                                            <input type="hidden" name="_token" value="8WH63seUHqELXf6NFMv5FY6OYHbvYZoVVrBeoQAR">
                                        </form>
                                    </li>
                                </ul>
                            </li>
                                        </ul>
                </div>
            </div>
        </nav>
                <div id='video-upload-component'>
            <video-upload></video-upload>
        </div>

        <!-- Scripts -->
        <script src="http://view.app:8000/js/app.js"></script>
    </body>
    </html>

【问题讨论】:

    标签: php laravel vue.js vuejs2 vue-resource


    【解决方案1】:

    您需要发送 CSRF 令牌。

    在 HEAD 元素中添加:

    &lt;meta name="csrf-token" content="{{ csrf_token() }}"&gt;

    如果你使用 jQuery:

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

    【讨论】:

    • 我应该把 $.ajaxSetup 行放在哪里?
    • 你可以把它放在你想使用ajax逻辑的页面中,在脚本元素里面
    【解决方案2】:

    根据您的“XHR 错误”,这意味着当您发出 post 请求时,您没有发送 CSRF 令牌。

    根据 laravel 路由规则,中间件起作用,不同的中间件之间有 ValidateCSRFToken。这是检查您是否发送有效的 CSRF 令牌。

    请将其添加到您的 AJAX 请求中。

    看看,是否可行。

    【讨论】:

    • 我添加了扩展 app.blade.php 的 upload.blade.php 文件。我相信引用了 csrf-token,但也许我做错了。感谢您的帮助。
    • 您可以做的两件事来确保 csrf 令牌已通过,1. 查看代码的视图源并查看 csrf 令牌 html 元素是否介于 &lt;form&gt;...&lt;/form&gt; 之间 2. 检查检查元素时的 XHR 部分。
    • 我发布了源代码。因为我只选择要上传的文件,所以在我在 XHR 中获取 UID 之前就发生了错误。
    • 我不知道UID是什么,当你发出一个post请求时,你可以检查那个请求的参数部分。
    猜你喜欢
    • 1970-01-01
    • 2017-06-30
    • 2018-10-16
    • 2021-11-14
    • 2017-02-15
    • 2023-03-13
    • 1970-01-01
    • 2017-02-19
    • 2017-04-21
    相关资源
    最近更新 更多