使用 Laravel、Vue-2、vue-composer 在 Ajax 中发布错误
Posted
技术标签:
【中文标题】使用 Laravel、Vue-2、vue-composer 在 Ajax 中发布错误【英文标题】:POST Error in Ajax with Laravel, Vue-2, vue-composer 【发布时间】: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 */↵ htmlcolor:#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,tdmargin:0;padding:0;tableborder-collapse:collapse;border-spacing:0;fieldset,imgborder:0;address,caption,cite,code,dfn,em,strong,th,varfont-style:normal;font-weight:normal;lilist-style:none;caption,thtext-align:left;h1,h2,h3,h4,h5,h6font-size:100%;font-weight:normal;q:before,q:aftercontent:'';abbr,acronymborder:0;font-variant:normal;supvertical-align:text-top;subvertical-align:text-bottom;input,textarea,selectfont-family:inherit;font-size:inherit;font-weight:inherit;input,textarea,select*font-size:100%;legendcolor:#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">
</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>
【问题讨论】:
【参考方案1】:您需要发送 CSRF 令牌。
在 HEAD 元素中添加:
<meta name="csrf-token" content=" csrf_token() ">
如果你使用 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 元素是否介于<form>...</form>
之间 2. 检查检查元素时的 XHR 部分。
我发布了源代码。因为我只选择要上传的文件,所以在我在 XHR 中获取 UID 之前就发生了错误。
我不知道UID是什么,当你发出一个post请求时,你可以检查那个请求的参数部分。以上是关于使用 Laravel、Vue-2、vue-composer 在 Ajax 中发布错误的主要内容,如果未能解决你的问题,请参考以下文章
VueJS 2 vue-router 2 (laravel 5.3)
Gulp:找不到模块'laravel-elixir-vue-2'
如何将数组从 Laravel Blade 传递到 Laravel 6/Vue 2.6 中的 Vue 组件。*