關鍵點在於不論是 XMLHttpRequest 或者是用 ajax,只要有夾帶 authroization (user name & password) 要做認證的話,會多一個 OPTIONS request,而且 javascript 這邊也要做修改。
注意: 這是很不安全的CORS,有可能被釣魚,所以盡可能不要使用
一般狀況下透過 XMLHttpRequest 或 ajax 去呼叫其他 server 上的 api 或網頁,只要對方 server 的 cors 設定有做好就沒問題,但是如果要加上 authorization 資訊,javascript 這邊要指定這個 request 必須是 with credentials,且要把 authorization 資料放在 header 中。
<!DOCTYPE html>
<html>
<head>
<meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
</head>
<body>
<div class="container" style="padding-top:40px;">
<span id="i01">test</span>
<span id="i02">test2</span>
</div>
</body>
<script>
// jquery
$('#i01').click(function(){
$.ajax({
type: "GET",
url: "http://API.SERVER.URL/PATH/TO/API",
dataType: 'json',
async: false,
beforeSend: function(request){
request.withCredentials = true;
request.setRequestHeader("Authorization" , "Basic AUTHORIZATION_DATA=="); // AUTHORIZATION_DATA = btoa("USERNAME:PASSWORD");
},
success: function (){
alert('Success!');
}
});
});
// javascript
$('#i02').click(function(){
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert('Success!');
}
};
var url = 'ttp://API.SERVER.URL/PATH/TO/API';
xhttp.open("GET", url, true);
xhttp.setRequestHeader('Authorization','Basic AUTHORIZATION_DATA=='); // AUTHORIZATION_DATA = btoa("USERNAME:PASSWORD");
xhttp.send();
});
</script>
</html>
而在被呼叫的 api 部分(以 php phalcon framework 為例子),則不僅要把 X-Requested-With 加入 allow headers 裏頭,連 Authorization 也要。
public function apiAction()
{
$resp = new PhalconHttpResponse();
$resp->setHeader("Access-Control-Allow-Origin", "*");
$resp->setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Authorization');
$resp->sendHeaders();
$this->view->disable();
//$headers = apache_request_headers();
//var_dump($headers['Authorization']);
$resp->setHeader("Content-Type", "application/json");
$resp->setStatusCode(200, "OK");
$resp->setContent('{"message": "Not a valid verifiy"}');
$resp->send();
return;
}
最後就可以看到這樣的結果。