AJAX(XMLHttpRequest)進行跨域請求方法詳解(二)
2,預檢請求
預檢請求首先需要向另外一個域名的資源傳送一個 HTTP OPTIONS 請求頭,其目的就是為了判斷實際傳送的請求是否是安全的。下面的2種情況需要進行預檢:
a,不是上面的簡單請求,比如使用Content-Type 為 application/xml 或 text/xml 的 POST 請求
b,在請求中設定自定義頭,比如 X-JSON、X-MENGXIANHUI 等
注意:在 iis 裡進行測試,必須在“應用程式擴充套件”裡面配置 .aspx 擴充套件的動作允許 OPTIONS。
下面我們舉一個預檢的請求:
br> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
孟憲會之AJAX跨域請求測試
// var xhr = new XMLHttpRequest();
var url = 'http://dotnet.aspx.cc/PreflightedRequests.aspx';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "開始進行請求……";
if (xhr) {
var xml = "測試 ";
xhr.open('POST', url, true);
xhr.setRequestHeader("POWERED-BY-MENGXIANHUI", "Approve");
xhr.setRequestHeader("Content-Type", "application/xml");
xhr.onreadystatechange = handler;
xhr.send(xml);
} else {
document.getElementById("content").innerHTML = "不能建立 XMLHttpRequest。";
}
}
function handler(evtXHR) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var response = xhr.responseText;
document.getElementById("content").innerHTML = "結果:" + response;
} else {
document.getElementById("content").innerHTML = "不能進行跨越訪問。";
}
}
else {
document.getElementById("content").innerHTML += "
執行狀態 readyState:" + xhr.readyState;
}
}
//]]>
上面的例子我們傳送 xml 格式的資料,並且,傳送一個非標準的HTTP頭 POWERED-BY-MENGXIANHUI 來說明伺服器端該如何設定響應頭的。
在伺服器端,PreflightedRequests.aspx 的內容如下:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod.Equals("GET"))
{
Response.Write("這個頁面是用來測試跨域 POST 請求的,直接瀏覽意義不大。");
}
else if (Request.HttpMethod.Equals("OPTIONS"))
{
//通知客戶端允許預檢請求。並設定快取時間
Response.ClearContent();
Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");
Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
Response.AddHeader("Access-Control-Allow-Headers", "POWERED-BY-MENGXIANHUI");
Response.AddHeader("Access-Control-Max-Age", "30");
//此過程無需返回資料
Response.End();
}
else if (Request.HttpMethod.Equals("POST"))
{
if (Request.Headers["Origin"].Equals("http://www.meng_xian_hui.com:801"))
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(Request.InputStream);
Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");
Response.Write("您提交的資料是:
" + Server.HtmlEncode(doc.OuterXml));
}
else
{
Response.Write("不允許你的網站請求。");
}
}
}
點選“開始測試”按鈕,將會執行下面的一系列請求。
OPTIONS /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Origin: http://www.meng_xian_hui.com:801
Access-Control-Request-Method: POST
Access-Control-Request-Headers: powered-by-mengxianhui
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:00:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: POWERED-BY-MENGXIANHUI
Access-Control-Max-Age: 30
Set-Cookie: ASP.NET_SessionId=5npqri55dl1k1zvij1tlw3re; path=/; HttpOnly
Cache-Control: private
Content-Length: 0
POST /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
POWERED-BY-MENGXIANHUI: Approve
Content-Type: application/xml; charset=UTF-8
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
Content-Length: 19
Origin: http://www.meng_xian_hui.com:801
Pragma: no-cache
Cache-Control: no-cache
測試
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:00:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Set-Cookie: ASP.NET_SessionId=byvose45zmtbqy45d2a1jf2i; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 65
以上的程式碼反映了預檢請求的執行過程:首先傳送 OPTIONS 請求頭,用來向伺服器諮詢伺服器的更多資訊,以便為後續的真實請求做準備。比如是否支援 POST 方法等。值得注意的是:
瀏覽器還傳送 Access-Control-Request-Method: POST 和 Access-Control-Request-Headers: powered-by-mengxianhui 請求頭。
注意:以上過程是第一次請求的時候的過程,如果在 30 秒內重複點選按鈕,你可以看不到 OPTIONS 這一過程。則執行過程是這樣的:
POST /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
POWERED-BY-MENGXIANHUI: Approve
Content-Type: application/xml; charset=UTF-8
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
Content-Length: 19
Origin: http://www.meng_xian_hui.com:801
Pragma: no-cache
Cache-Control: no-cache
測試
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:06:32 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Set-Cookie: ASP.NET_SessionId=qs1c4urxywdbdx55u04pvual; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 65
為什麼會這樣?細心的童鞋可能注意到了,在伺服器端有一行程式碼 Response.AddHeader("Access-Control-Max-Age", "30"); 它是用來設定預檢的有效時間的,單位是秒。這一點要特別注意。
預檢請求首先需要向另外一個域名的資源傳送一個 HTTP OPTIONS 請求頭,其目的就是為了判斷實際傳送的請求是否是安全的。下面的2種情況需要進行預檢:
a,不是上面的簡單請求,比如使用Content-Type 為 application/xml 或 text/xml 的 POST 請求
b,在請求中設定自定義頭,比如 X-JSON、X-MENGXIANHUI 等
注意:在 iis 裡進行測試,必須在“應用程式擴充套件”裡面配置 .aspx 擴充套件的動作允許 OPTIONS。
下面我們舉一個預檢的請求:
br> "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
// var xhr = new XMLHttpRequest();
var url = 'http://dotnet.aspx.cc/PreflightedRequests.aspx';
function crossDomainRequest() {
document.getElementById("content").innerHTML = "開始進行請求……";
if (xhr) {
var xml = "
xhr.open('POST', url, true);
xhr.setRequestHeader("POWERED-BY-MENGXIANHUI", "Approve");
xhr.setRequestHeader("Content-Type", "application/xml");
xhr.onreadystatechange = handler;
xhr.send(xml);
} else {
document.getElementById("content").innerHTML = "不能建立 XMLHttpRequest。";
}
}
function handler(evtXHR) {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
var response = xhr.responseText;
document.getElementById("content").innerHTML = "結果:" + response;
} else {
document.getElementById("content").innerHTML = "不能進行跨越訪問。";
}
}
else {
document.getElementById("content").innerHTML += "
執行狀態 readyState:" + xhr.readyState;
}
}
//]]>
上面的例子我們傳送 xml 格式的資料,並且,傳送一個非標準的HTTP頭 POWERED-BY-MENGXIANHUI 來說明伺服器端該如何設定響應頭的。
在伺服器端,PreflightedRequests.aspx 的內容如下:
protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod.Equals("GET"))
{
Response.Write("這個頁面是用來測試跨域 POST 請求的,直接瀏覽意義不大。");
}
else if (Request.HttpMethod.Equals("OPTIONS"))
{
//通知客戶端允許預檢請求。並設定快取時間
Response.ClearContent();
Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");
Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
Response.AddHeader("Access-Control-Allow-Headers", "POWERED-BY-MENGXIANHUI");
Response.AddHeader("Access-Control-Max-Age", "30");
//此過程無需返回資料
Response.End();
}
else if (Request.HttpMethod.Equals("POST"))
{
if (Request.Headers["Origin"].Equals("http://www.meng_xian_hui.com:801"))
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load(Request.InputStream);
Response.AddHeader("Access-Control-Allow-Origin", "http://www.meng_xian_hui.com:801");
Response.Write("您提交的資料是:
" + Server.HtmlEncode(doc.OuterXml));
}
else
{
Response.Write("不允許你的網站請求。");
}
}
}
點選“開始測試”按鈕,將會執行下面的一系列請求。
OPTIONS /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Origin: http://www.meng_xian_hui.com:801
Access-Control-Request-Method: POST
Access-Control-Request-Headers: powered-by-mengxianhui
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:00:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: POWERED-BY-MENGXIANHUI
Access-Control-Max-Age: 30
Set-Cookie: ASP.NET_SessionId=5npqri55dl1k1zvij1tlw3re; path=/; HttpOnly
Cache-Control: private
Content-Length: 0
POST /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
POWERED-BY-MENGXIANHUI: Approve
Content-Type: application/xml; charset=UTF-8
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
Content-Length: 19
Origin: http://www.meng_xian_hui.com:801
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:00:34 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Set-Cookie: ASP.NET_SessionId=byvose45zmtbqy45d2a1jf2i; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 65
以上的程式碼反映了預檢請求的執行過程:首先傳送 OPTIONS 請求頭,用來向伺服器諮詢伺服器的更多資訊,以便為後續的真實請求做準備。比如是否支援 POST 方法等。值得注意的是:
瀏覽器還傳送 Access-Control-Request-Method: POST 和 Access-Control-Request-Headers: powered-by-mengxianhui 請求頭。
注意:以上過程是第一次請求的時候的過程,如果在 30 秒內重複點選按鈕,你可以看不到 OPTIONS 這一過程。則執行過程是這樣的:
POST /PreflightedRequests.aspx HTTP/1.1
Host: dotnet.aspx.cc
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.2; zh-CN; rv:1.9.1.7) Gecko/20091221 Firefox/3.5.7 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-cn,zh;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
POWERED-BY-MENGXIANHUI: Approve
Content-Type: application/xml; charset=UTF-8
Referer: http://www.meng_xian_hui.com:801/CrossDomainAjax/PreflightedRequests.html
Content-Length: 19
Origin: http://www.meng_xian_hui.com:801
Pragma: no-cache
Cache-Control: no-cache
HTTP/1.x 200 OK
Date: Sun, 10 Jan 2010 14:06:32 GMT
Server: Microsoft-IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Access-Control-Allow-Origin: http://www.meng_xian_hui.com:801
Set-Cookie: ASP.NET_SessionId=qs1c4urxywdbdx55u04pvual; path=/; HttpOnly
Cache-Control: private
Content-Type: text/html; charset=utf-8
Content-Length: 65
為什麼會這樣?細心的童鞋可能注意到了,在伺服器端有一行程式碼 Response.AddHeader("Access-Control-Max-Age", "30"); 它是用來設定預檢的有效時間的,單位是秒。這一點要特別注意。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/15723462/viewspace-624783/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Ajax 跨域請求 Access to XMLHttpRequest 解決方案跨域XMLHTTP
- js ajax請求封裝及解決node請求跨域問題JS封裝跨域
- Ajax+SpringMVC實現跨域請求SpringMVC跨域
- ajax跨域請求之CORS的使用跨域CORS
- 詳解XMLHttpRequest的跨域資源共享XMLHTTP跨域
- 跨域請求cookie資源共享詳解跨域Cookie
- AJAX 跨域請求解跨域
- Python全棧Web(AjaxJQuery-AJAX跨域請求)Python全棧WebjQuery跨域
- java解決請求跨域的兩種方法Java跨域
- 跨域請求跨域
- Koa2框架利用CORS完成跨域ajax請求框架CORS跨域
- 跨域請求之jQuery的ajax jsonp的使用解惑跨域jQueryJSON
- springboot 解決跨域 Access to XMLHttpRequest atSpring Boot跨域XMLHTTP
- csrf解決Ajax請求跨站問題
- 解決 jquery使用ajax請求發生跨域問題的辦法jQuery跨域
- 跨域是什麼?跨域請求資源有哪些方法?跨域
- vue跨域請求Vue跨域
- CORS跨域請求CORS跨域
- 前後端資料互動(二)——原生 ajax 請求詳解後端
- 解決 ajax 跨域跨域
- SpringBoot解決跨域請求攔截Spring Boot跨域
- 巧用javascript ajax,實現跨域請求外帶,增大漏洞危害JavaScript跨域
- 盤點 Spring Boot 解決跨域請求的幾種方法Spring Boot跨域
- 允許跨域請求跨域
- vue axios 請求跨域VueiOS跨域
- 前端http請求跨域問題解決前端HTTP跨域
- 解決ajax跨域問題的多種方法跨域
- Vue——介面請求支援跨域Vue跨域
- 同源政策與跨域請求跨域
- Cross-origin 跨域請求ROS跨域
- 跨域請求後端配置跨域後端
- php 支援jsonp跨域請求PHPJSON跨域
- NGINX如何配置跨域請求Nginx跨域
- React 解決fetch跨域請求時session失效React跨域Session
- Springboot處理CORS跨域請求的三種方法Spring BootCORS跨域
- ajax請求
- IE9 跨域請求相容IE9跨域
- 跨域之OPTION請求【轉載】跨域
- web 跨域請求安全問題Web跨域