Laravel使用記錄(十一)表單驗證(四)

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響應,參考這裏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章