AJAX請求和驗證
雖然上述教程已經能夠完成表單驗證,但是在實際應用中,很少使用,畢竟提交觸發了刷新操作,把原來填寫的字段內容都重置爲空了,用戶體驗十分不友好,所以我們今天來介紹一種友好的提交方式:AJAX。
先附上一個完整可用代碼,只是更改了控制器和視圖的部分代碼,大環境仍然可以參考上述教程。
視圖
<ul id="errors"></ul>
<form method="post" action="{{url('registerStore')}}">
<p>username:<input type="text" name="username" id="username"/></p>
<p>password:<input type="password" name="password" id="password"/></p>
<p><input type="button" value="submit" id="submit"></p>
</form>
<script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
<script>
$("#submit").click(function(){
var username = $("#username").val();
var password = $("#password").val();
var token = '{{ csrf_token() }}';
$.ajax({
type : 'post',
url : '/registerStore',
data : {'username': username, 'password': password, '_token': token},
dataType: 'json',
success: function(data){
$("#errors").html('');
},
error: function(data){
if(data.responseJSON){
var errors = data.responseJSON.errors;
var html = '';
$.each(errors, function(error_index, error){
$.each(error, function(msg_index, msg){
html += '<li>'+msg+'</li>';
});
});
$("#errors").html(html);
}
}
});
});
</script>
控制器
public function registerStore(RegisterRequest $request)
{
$result = ['status'=> 0, 'msg'=> 'success'];
return $result;
}
基於以上代碼,我們來說一下注意事項
1.HTTP狀態碼419問題
是不是很熟悉,不錯就是表單中的419問題。但是ajax中又不能加 {{ csrf_field() }},該如何解決呢?如果你熟悉文檔的話,應該會看到解決辦法。
首先加meta標籤
<meta name="csrf-token" content="{{ csrf_token() }}">
然後在ajax傳輸前設置header。
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
因爲CSRF保護除了會檢查POST參數中的CSRF令牌外,還會檢查X-CSRF-TOKEN請求頭,兩者取其一即可。但是不覺得這麼做有些麻煩嗎,沒有簡單的辦法?當然有。如果你仔細觀察的話, {{ csrf_field() }}是創建了一個隱藏的input,隨着表單一起提交,如果我們在ajax提交的時候,也整這麼一個字段的話,是不是就可以了?當然可以。
那麼應該寫什麼字段名和字段值呢?字段名的話仔細觀察的 {{ csrf_field() }}輸出的input就能得出,_token。那麼字段值呢?其實就是meta中的{{ csrf_token() }} 。
2.ajax的success無反應問題
以前處理ajax的時候,無論驗證的字段是否通過,都會通過success來處理。但是這在Laravel的表單驗證是行不通的,因爲它返回的HTTP狀態碼是422,所以success是無法接收到的,我們需要使用error來處理。這裏需要說明一點的是,跟平時我們使用success不同的是,data並非都是我們需要的數據,我們需要的只是data.responseJSON,而錯誤信息則在data.responseJSON.errors中。
3.控制器方法是否需要返回數據
如果ajax中定義了dataType爲JSON,則控制器方法中必須返回JSON數據,如果返回的格式不是JSON,例如返回空,則無法觸發success。
如果沒有定義dataType,則控制器方法中可以不用書寫任何代碼。
return一個數組的情況下,框架會自動將數組轉化爲JSON響應,參考這裏。