當AJAX碰上CORS
看到 error message 出現 CORS 的幾種情形
身為一位前端網頁設計師,會遇到的錯誤訊息種類不會太多或是太複雜解決,其中最令我傷透腦筋應該非CORS莫屬,不但錯誤訊息又臭又長,看完也無從下手,是否該修改網站的設定檔或是怎麼做網頁的宣告,以下我們將一步步慢慢探討各種有可能遇到的情形。
以下從我實際遇到的一個例子來說起:
當我們提交表單想把表單資料存入資料庫的時候,我們會呼叫$.ajax();
,其中有一個data
參數,在這裡我們將要傳送到server的資料指派給它:
var formData = $(‘form’).serialize();$.ajax(function() {
...
data: formData;
...
})
formData
裡面裝了什麼東西呢?
$('form')
在呼叫.serialize()
後會得到一個集結了所有表單資料的字串,如同將整個表單的資料打包成一包,這樣比一個欄位一欄位呼叫.val()
的方式來得容易多了。
The .serialize() method creates a text string in standard URL-encoded notation.
在呼叫.serialize()
後,表單的資料會轉換成以key-value成對的形式,如此在傳送表單前對表單資料進行事先處理,之後在取得、使用某個欄位的資料便能很輕而易舉地做對應。
在input名稱(name屬性)為message和name的欄位中分別輸入”A cup of tea”和”Panda”。經過.serialize()
得到的結果如下:
message=A%20cup%20of%20tea&name=Panda
接著就是進入$.ajax()
進重頭戲的部分。以下是完整呼叫$.ajax()
的程式碼:
var formData = $('form').serialize();$.ajax({
type: 'POST',
url: 'fakeURL',
data: formData,
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
error: function(jqXHR) {
console.log('Error: ' + jqXHR.status);
}
});
注意一下contentType
這個參數,這是用來告訴 server 它即將接收到的資料是什麼類型。由於表單資料在呼叫.serialize()
之後得到的字串,型態跟MIME的application/x-www-form-urlencoded
相同,因此我們將contentType
的值設為application/x-www-form-urlencoded
。
$.ajax()
的contentType
在未指定的時候,預設值即為application/x-www-form-urlencoded
。
For cross-domain requests, setting the content type to anything other than application/x-www-form-urlencoded
, multipart/form-data
, or text/plain
will trigger the browser to send a preflight OPTIONS request to the server.
如上所述,如果contentType的值設為application/x-www-form-urlencoded
、multipart/form-data
、text/plain
三者之外的值,就會觸發瀏覽器發送一個Preflight Request(預檢請求)到server−即呼叫OPTIONS
function,此為在發送真正的request前所做的確認動作,目的是去檢查請求方是否為安全、可信賴的網域。如果Preflight Request不被允許的話,真正的請求就不會被送出。我們可以從開發者工具中的Network面板中檢視:
小插曲
在執行$.ajax()
時為了確保請求有得到正確的回應,使用console.log()
印出 Http response code,得到的是表示請求成功的代碼200,但同時error
callback function也被觸發了,這是為什麼呢?原因就出在dataType
屬性。
我們設定dataType
是用來告訴接收請求的server端,將資料轉換成指定的資料型態,如果資料在轉換的過程產生了任何錯誤,都有可能導致error
的觸發,此時可以試著將dataType
先註解掉以釐清程式碼執行錯誤的原因。
此時將error callback function的第二個參數印出來可以馬上應證是資料在轉換上發生問題:parseerror
error: function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
}
參考資料:
https://blog.techbridge.cc/2017/05/20/api-ajax-cors-and-jsonp/
https://kjj6198.github.io/2019/01/18/cors-and-cookie/
https://imququ.com/post/four-ways-to-post-data-in-http.html
https://stackoverflow.com/questions/6186770/ajax-request-returns-200-ok-but-an-error-event-is-fired-instead-of-success
喜歡本篇文章,歡迎按下Medium的「claps」以及LikeCoin的「Like」給我們鼓勵鼓勵!
若是長按50下我們會明白你更喜歡這類型的文章,會讓之後的編輯盡量發揮這部分的內容!
LikeCoin的「Like」是能讓我們收到一點點支持的簡單按鈕,請幫我們點至+5。