[Ajax] 如何製作 header 傳送及接收資料以及 CORS 問題


如何製作 header 傳送及接收資料

之前想說在header帶上參數,就可以POST到另一個API調用資料,這是一件很單純的問題,沒想到竟然這麼多問題啊!!

研究了很久,怎麼傳都無法傳過去,

  1. 先是 CROS (Cross-origin resource sharing)
  2. header 設定方式
  3. 接收 header 的一些基本問題

以下是 ajax 的範例表式。

1.以下是 ajax 的範例表式,兩種方式都可以

使用 headers {key:value} 來傳送資料

function uploadfile(){
    var url = 'http://tt.bbb.com/';
    $.ajax({
        url     : url,
        dataType: 'json',
        data    : 'tttt',
        type    : 'POST',
        headers : {
            'ver'      : '1.0',
            'fileType' : 'mp4',
            'md5'  : '47e954ec481d097e96261d993ec43ba5',
            'fileSize' : 276505673
        },
        success: function(data) {
            console.log(data);
        }
    });
}

 

使用beforeSend:function來傳送資料

function uploadfile(){
    var url = 'http://tt.bbb.com/';
    $.ajax({
        url     : url,
        dataType: 'json',
        data    : 'tttt',
        type    : 'POST',
        beforeSend:function(xhr){
            xhr.setRequestHeader('ver','1.0');
            xhr.setRequestHeader('fileType','mp4');
            xhr.setRequestHeader('md5','47e954ec481d097e96261d993ec43ba5');
            xhr.setRequestHeader('fileSize',276505673);
        },
        success: function(data) {
            console.log(data);
        }
    });
}

 

2.Server 端的設定

<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE');
header('Access-Control-Allow-Headers: *');
header('Access-Control-Allow-Credentials: true');
header('Access-Control-Expose-Headers: *');
header('Ver:1.0.1');
header('Status:OK');
header('StatusNum:200');
header('Msg:succuss');
?>

從這個 PHP 範例可以看到,都是 header,這就是要設定讓其它非相同網域使用者可以傳送值過來。

header(‘Access-Control-Allow-Origin: *’);

允許 * 任何 來源連線

header(‘Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE’);

允許 使用POST, GET, OPTIONS, PUT, DELETE 方式連線

header(‘Access-Control-Allow-Headers: *’);

允許 * 任何 header參數連線

header(‘Access-Control-Expose-Headers: *’);

允許 * 任何 header參數 可以被取得
(最後就是掛在這,因為要實現取得header回傳的資料,這部份要開啟)
例如,只允許開始四個參數名可存取的話也可以這樣寫
header(‘Access-Control-Expose-Headers: Ver, Status, StatusNum, Msg’);

3.如何取得 header 的 ajax 方式

使用 success 的回傳 (data, status, xhr), xhr.getResponseHeader(‘KEY’); 即可

function uploadfile(){
    var url = 'http://tt.bbb.com/';
    $.ajax({
        url     : url,
        type    : 'POST',
        headers : {
            'ver'      : '1.0',
            'fileType' : 'mp4',
            'fileMd5'  : '47e954ec481d097e96261d993ec43ba5',
            'fileSize' : 276505673
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            console.log(XMLHttpRequest);
            console.log(textStatus);
            console.log(errorThrown);
        },
        success: function(data, status, xhr) { 
            console.log(xhr.getResponseHeader('Ver'));
            console.log(xhr.getResponseHeader('Status'));
            console.log(xhr.getResponseHeader('StatusNum'));
            console.log(xhr.getResponseHeader('Msg'));
        },
        failure: function(data) {
            console.log(data);
        }
    });
}

4.另外補充說明一下有關 Options 的部份

你知道在使用 Ajax POST 時,在Chrome develop 上面會看到兩次的連線,是為什麼呢?這就是CROS在確認你的連線請求的權限。

如下圖,目地的是 tt.bbb.com 但在連線狀態這裡出現了兩次的連線。這個部份我們稱為 Preflight Request,中文叫「預檢請求」。

第一次請求是用 Options 主要是確認來源是否有使用的權限,如果有的話,才會進行至正式流程,如果沒有開啟對應的權限,你的headers的 key : value 就會變成下面這樣一串 Access-Control-Request-Headers: filemd5, filesize, filetype, ver ,Server端就一直無法解析。

 

如果你的目的地主機設定都是正常的,那你就會進入 POST 流程,然後你的Request Headers 就會看到正常的資料,Key : Value 都是一組一組的。