利用JSONP/ CORS實現Cross-Origin Request

目前跨域請求常見的做法有兩種,在這裡分別用JSONP和CORS來做實現。
- JSONP:利用<script> src可以cross domain獲取資源的特性來做實現,通常會帶一個callback的參數過去供server端呼叫。 這是jQuery的做法,利用$.ajax去動態生成一個<script> tag作實現。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function jsonpCallback(data) { // 需要public出來,不然會呼叫不到!
    console.log(data);
}
function remote() {
    $.ajax({
        url: "http://demosite2013.herokuapp.com/exercise/crossDomain/jsonp.php",
        dataType: "jsonp",
        jsonpCallback: "jsonpCallback",
        success: function(data) {
            console.log("success: " + data);
        }
    });
}

jQuery(document).ready(function(){
    remote();
});

也可以利用<script> tag直接呼叫:

1
<script type="text/javascript" src="http://demosite2013.herokuapp.com/exercise/crossDomain/jsonp.php?callback=jsonpCallback"></script>

Server端的寫法:

1
2
3
4
<?php header('content-type: application/json; charset=utf-8');
    $data = "這是Server回傳資料!";
    echo $_GET['callback'].'('.json_encode($data).')';
?>

- CORS:最近常見也是W3C推薦的做法。 Client端只要依照一般的ajax request要求即可,這裡用jQuery來實現。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 (function (window, document, undefined) {
    function remote() {
        $.ajax({
            url: "http://demosite2013.herokuapp.com/exercise/crossDomain/cors.php",
            success: function(data) {
                console.log("success: " + data);
            }
        });
    }

    jQuery(document).ready(function(){
        remote();
    });
})(window, document);

Server端的寫法比較要考慮是否要接受/拒絕cross domain requests:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php header('content-type: application/json; charset=utf-8');
    if ($_SERVER['REQUEST_METHOD'] == "OPTIONS") {
        // Tell the Client we support invocations and that this preflight holds good for only 20 days
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
        header('Access-Control-Max-Age: 1728000');
        header("Content-Length: 0");
        header("Content-Type: application/json");
    } elseif($_SERVER['REQUEST_METHOD'] == "GET" || "POST") {
        header('Access-Control-Allow-Origin: *');
        header('Content-Type: application/json');
        $data = "這是Server回傳資料!";
        echo json_encode($data);
    } else {
        die("No Other Methods Allowed");
    }
?>

如果沒有瀏覽器相容性的要求,建議是以CORS實現,彈性比較大也可以發post request;如果使用JSONP的話只能處理get request,而且也不算是Ajax的實現。