寫對外公開 WebAPI 時,會因為瀏覽器安全性的關係而禁止非同源存取。
如以下範例:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">在這裡模擬 XMLHttpRequest 對公開 WebAPI 進行登入,接著瀏覽器很不客氣的回應了:
<html>
<head>
<title></title>
<script type="text/javascript" src="js/base64.js"></script>
<script type="text/javascript" src="js/json-min.js"></script>
<script type="text/javascript" src="js/serverfunctionexecutor.js"></script>
<script type="text/javascript" src="js/connection.js"></script>
</head>
<body>
<form onsubmit="event.preventDefault();myFunction()">Enter name: <input type="TEXT"> Enter password: <input type="PASSWORD">
<input type="submit" value="Login">
</form>
<script>
"use strict"
function myFunction() {
var request = getXmlHttpObject()
request.open("GET", "http://localhost:8080/datasnap/rest/TServerMethods1/EchoString/A B C", true);
request.onreadystatechange = function() {
if (request.readyState == 4)
{
var JSONResult = parseHTTPResponse(request)
console.log(JSONResult.result[0])
}
}
request.setRequestHeader("Accept", "application/json");
request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
request.setRequestHeader("If-Modified-Since", "Mon, 1 Oct 1990 05:00:00 GMT");
request.send();
}
</script>
</body>
</html>
再看看網路頁籤是如何發送 XHR 的訊息:
跨來源資源共用標準的運作方式是藉由加入新的 HTTP 標頭讓伺服器能夠描述來源資訊以提供予瀏覽器讀取。另外,針對會造成副作用的 HTTP 請求方法(特別是GET
以外的 HTTP 方法,或搭配某些 MIME types 的POST
方法),規範要求瀏覽器必須要請求傳送「預檢(preflight)」請求,以 HTTP 的OPTIONS
方法之請求從伺服器取得其支援的方法。當伺服器許可後,再傳送 HTTP 請求方法送出實際的請求。伺服器也可以通知客戶端是否要連同安全性資料(包括 Cookies 和 HTTP 認證(Authentication)資料)一併隨請求送出。
於是要在後端讓 WebAPI 修正到能接受 OPTIONS 請求。
第二次發送,成功了……沒有,但回傳另一個錯誤訊息:
缺少 Access-Control-Allow-Origin 檔頭,原來如此,這檔頭又要表示什麼呢?MDN 是這麼解釋的:
從 Origin 標頭與 Access-Control-Allow-Origin 標頭中可以看到存取控制協定最簡單的用途。這個例子中,伺服器回傳 Access-Control-Allow-Origin: * 表示允許任何網域跨站存取資源,倘若 http://bar.other 的資源擁有者只准許來自 http://foo.example 的存取資源請求,那麼將會回傳:
Access-Control-Allow-Origin: http://foo.example
如此一來,來源並非 http://foo.example 網域(由第 10 行請求標頭中的 ORIGIN 標頭確認)便無法以跨站的方式存取資源。Access-Control-Allow-Origin 標頭必須包含請求當中的 Origin 標頭值。
這裡的來源指的是 Server 允許來自何處的 Client,以這個例子來說:
- localhost:8080 = Server
- localhost:9000 = Client
所以要允許的是 localhost:9000 的存取,當然,使用【*】也是可以的。
Server 端是如何編寫 CORS 配置?
敬請期待下回,或是搶先看這裡。
沒有留言:
張貼留言