ユーザーがテキスト領域内にのみテキストを入力する必要があるこのフォームがあります:
<form action="#" v-on:submit="postStatus">{{-- Name of the method in Vue.js --}}
<div class="form-group">
<textarea class="form-control" rows="5" maxlength="140" autofocus placeholder="What are you upto?" required v-model="post"></textarea>
</div>
<input type="submit" value="Post" class="form-control btn btn-info">
{{ csrf_field() }}
</form>
次に、そのテキストをコントローラーに渡し、最終的にデータベースに保存するために、ajaxでvue.jsを使用している次のスクリプトコードがあります。
//when we actually submit the form, we want to catch the action
new Vue({
el : '#timeline',
data : {
post : '',
},
http : {
headers: {
'X-CSRF-Token': $('meta[name=_token]').attr('content')
}
},
methods : {
postStatus : function (e) {
e.preventDefault();
console.log('Posted: '+this.post+ '. Token: '+this.token);
$.ajax({
url : '/posts',
type : 'post',
dataType : 'json',
data : {
'body' : this.post,
}
});
}
},
});
ただし、このトークンの不一致の例外があるため、これは今のところ機能しません。私はそれを機能させる方法がわかりません。このトークン値をコントローラーに渡す方法。私は次を試しました:
1)フォーム内で、トークンにvue nameを追加しました:
<input type="hidden" name="_token" value="YzXAnwBñC7qPK9kg7MGGIUzznEOCi2dTnG9h9çpB" v-model="token">
2)このトークン値をvueに渡そうとしました:
//when we actually submit the form, we want to catch the action
new Vue({
el : '#timeline',
data : {
post : '',
token : '',
},
methods : {
postStatus : function (e) {
e.preventDefault();
console.log('Posted: '+this.post+ '. Token: '+this.token);
$.ajax({
url : '/posts',
type : 'post',
dataType : 'json',
data : {
'body' : this.post,
'_token': this.token,
}
});
}
},
});
...しかし、コンソールでは、vueはキャッチさえしません:(
これにより、次のエラーが発生します。
VerifyCsrfToken.php行68のTokenMismatchException:
どうすれば修正できますか?何か案は?
次の2つの答えのおかげで解決しました。
1)最初に this one を読みました。
2)これ 2番目 。
したがって、私のフォームではこれを保持します:
{{ csrf_field() }}
そして、jsファイル内に次のものを追加するだけです(Vueインスタンス)の外側と上):
var csrf_token = $('meta[name="csrf-token"]').attr('content');
したがって、jsコード全体は次のようになります。
var csrf_token = $('meta[name="csrf-token"]').attr('content');
/*Event handling within vue*/
//when we actually submit the form, we want to catch the action
new Vue({
el : '#timeline',
data : {
post : '',
token : csrf_token,
},
methods : {
postStatus : function (e) {
e.preventDefault();
console.log('Posted: '+this.post+ '. Token: '+this.token);
$.ajax({
url : '/posts',
type : 'post',
dataType : 'json',
data : {
'body' : this.post,
'_token': this.token,
}
});
}
},
});
Very Easy Solution
非表示フィールドをフォーム内に追加するだけです。例
<form id="logout-form" action="/logout" method="POST" style="display: none;">
<input type="hidden" name="_token" :value="csrf">
</form>
このように、vueファイルで、script内にcsrf
変数を追加します。(data内にある必要があります)。
<script>
export default {
data: () => ({
csrf: document.querySelector('meta[name="csrf-token"]').getAttribute('content'),
}),
}
</script>
N.B。メタタグがblade.php
このようなファイル。
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
このようなものがない場合は、そこに配置する必要があります。
より良い方法は、スロットを介してcsrfトークンをvueコンポーネントに渡すだけです。
Blade.phpファイル内:
@extends('layouts.app')
@section('content')
<my-vue-component>
{{ csrf_field() }}
</my-vue-component>
@endsection
MyVueComponent.vueで
<form role="form">
<slot>
<!-- CSRF gets injected into this slot -->
</slot>
<!-- form fields here -->
</form>
単純に、これをPHPファイルに入れることをお勧めします。
<script>
window.Laravel = <?php echo json_encode(['csrfToken' => csrf_token()]); ?>
</script>
この方法で、JSパーツ(この場合はVue)からcsrfTokenを簡単にインポートできます。
さらに、このコードをPHPレイアウトファイルに挿入すると、window
はJSグローバル変数であるため、アプリの任意のコンポーネントでトークンを使用できます。
ソース: this postからトリックを得ました。
これに対する私の解決策は、すべてのvueコンポーネントがリクエストが行われる直前にcsrfトークンを取得することです。これをbootstrap.jsファイルに入れます。
Vue.http.interceptors.Push((request, next) => {
request.headers.set('X-CSRF-TOKEN', CoolApp.csrfToken);
next();
});
次に、クラスCoolApp.phpを用意します
public function getScriptVariables()
{
return json_encode([
'csrfToken' => csrf_token(),
]);
}