轉(zhuǎn)帖|其它|編輯:郝浩|2011-11-07 15:11:22.000|閱讀 650 次
概述:分享一下最近用jQuery跨域請(qǐng)求的經(jīng)歷,希望能給大家一些關(guān)于這個(gè)方案的概念和資料。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
分享一下最近用jQuery跨域請(qǐng)求的經(jīng)歷,希望能給大家一些關(guān)于這個(gè)方案的概念和資料。
該部分包括客戶端和服務(wù)器端,(如果服務(wù)器不在自己手上,那么還是考慮通過(guò)自己的服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求吧)
1.原本的代碼很簡(jiǎn)單,如果是同域名什么問(wèn)題都沒(méi)有 (有興趣的朋友可以嘗試在自己的服務(wù)器上運(yùn)行以下代碼)
$.ajax({
url: "//www.google.com/", //不同域名,而且google 沒(méi)有允許第三方提交所以會(huì)出錯(cuò)
cache: false,
//data: params,
dataType: 'json',
success: function (data) {
console.log(data);
},
error: function (e) {
alert(e.statusText);
}
})
嗯,我的默認(rèn)瀏覽器是Chrome, 上去一跑。。。當(dāng)然不能用。。。什么都還沒(méi)做呢,就想做跨域訪問(wèn)這么危險(xiǎn)的事情
下面是Chrome給出的錯(cuò)誤提示
![]()
2.在服務(wù)器端做點(diǎn)手腳,
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); // 可以設(shè)置為詳細(xì)的地址
3. 好了現(xiàn)在Chrome中的Get已經(jīng)可以運(yùn)行了,依葫蘆畫瓢開發(fā)了Post方法。。。。發(fā)現(xiàn)Post不能用。。。。- -# 真是不順利啊
在Fiddler中發(fā)現(xiàn)客戶端提交的是OPTIONS的請(qǐng)求.那就加一段邏輯處理OPTIONS
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); // 可以設(shè)置為詳細(xì)的地址
if (HttpContext.Current.Request.HttpMethod == "OPTIONS") // 加點(diǎn)邏輯
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept,X-Requested-With");
HttpContext.Current.Response.End();
}
實(shí)際運(yùn)行中有兩次請(qǐng)求 第一次是OPTIONS 第二次才是POST
4.還有問(wèn)題,忽然發(fā)現(xiàn)在IE8和IE9中無(wú)法運(yùn)行,而在其他的瀏覽器中都正常(opera未測(cè)試,google說(shuō)這個(gè)瀏覽器也有問(wèn)題。不過(guò)這東西比較小眾)
使用Fiddler發(fā)現(xiàn) 這個(gè)動(dòng)作根本沒(méi)有被提交到服務(wù)器端。
經(jīng)常Google以后發(fā)現(xiàn),IE8以上的版本跨域提交需要使用XDomainRequest 對(duì)象。(IE 為什么每次你都這么另類!,jQuery你為什么不兼容ie8和ie9的跨域提交功能。加點(diǎn)代碼很麻煩么?。。。?/p>
var xdr = new XDomainRequest();
xdr.onload = function (e) {
var data = $.parseJSON(xdr.responseText);
if (data == null || typeof (data) == 'undefined') {
data = $.parseJSON(data.firstChild.textContent);
}
//success
};
xdr.onerror = function (e) {
//error
}
xdr.open("GET", url);
xdr.send();
關(guān)于 XDomainRequest 請(qǐng)?jiān)谶@里查看詳細(xì),
5.恩 get功能在ie中也可以了, POST還不行,莫非又是IE的問(wèn)題? 這怎么每個(gè)功能都這么多問(wèn)題?
奇怪的是Fiddler中顯示IE8 中POST請(qǐng)求確實(shí)發(fā)出去了啊,怎么回事??
把問(wèn)題分解來(lái)看,吧fiddler獲取的http request raw數(shù)據(jù)拿出來(lái) 單獨(dú)提交試試,也不行?! 服務(wù)器返回415, 看來(lái)好像不是ie的問(wèn)題。(這次冤枉了它了)
仔細(xì)排查,發(fā)現(xiàn)缺少Content-Type(Content-Type其實(shí)不是必須的,參考RFC)
這坑爹的WCF 3.5啊, 不傳Content Type就給我報(bào)415異常 (WCF 4.0已經(jīng)解決這個(gè)問(wèn)題,3.5解決起來(lái)很麻煩,我一怒之下用了普通的ashx來(lái)處理)
what?!!! XDomainRequest 不能隨便設(shè)置header,
var xdr=new XDomainRequest ();
xdr.contentType="application/json"; //異常
xdr.contentType = "text/plain"; //
好吧javascript這邊設(shè)置失敗了,只能去服務(wù)器動(dòng)手腳,想死的心都有了,做點(diǎn)功能怎么這么麻煩。
到此為止,總算告一個(gè)段落了。
附錄1
用來(lái)解決跨域問(wèn)題的,服務(wù)器端代碼
public class Global : System.Web.HttpApplication
{
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (HttpContext.Current != null && HttpContext.Current.Response != null)
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", "*"); // take care
if (HttpContext.Current.Request.HttpMethod == "OPTIONS")
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, Accept,X-Requested-With");
HttpContext.Current.Response.End();
}
}
}
}
服務(wù)器也可以通過(guò)放置crossdomain.xml在根目錄下指定該邏輯,參考
附錄2 用來(lái)解決客戶端問(wèn)題的參考代碼(代碼比較潦草,不過(guò)重要的是邏輯)
function cloverGet(url, params, isRenderLoading, callback) {
if ($.browser.msie && parseInt($.browser.version, 10) >=
8 && window.XDomainRequest) {
var xdr = new XDomainRequest();
xdr.onload = function (e) {
var data = $.parseJSON(xdr.responseText);
if (data == null || typeof (data) == 'undefined') {
data = $.parseJSON(data.firstChild.textContent);
}
//需要手動(dòng)處理json數(shù)據(jù)
};
xdr.onerror = function (e) {
}
xdr.open("GET", url);
xdr.send();
}
else {
$.ajax({
url: url,
cache: false,
data: params,
dataType: 'json',
success: function (data) {
},
error: function (e) {
},
complete: function (e) {
},
beforeSend: function (xhr) {
}
});
}
}
function cloverPost(url, params, callback) {
if ($.browser.msie && parseInt($.browser.version, 10) >= 8 && window.XDomainRequest) {
var xdr = new XDomainRequest();
xdr.contentType = "text/plain";
xdr.onload = function () {
var data = $.parseJSON(xdr.responseText);
if (data == null || typeof (data) == 'undefined') {
data = $.parseJSON(data.firstChild.textContent);
}
//需要手動(dòng)格式化
};
xdr.onerror = function (e) {
}
xdr.open("POST", url);
xdr.send(params); //這里的數(shù)據(jù)是 a=1&b=2這樣的
}
else {
$.ajax({
type: "POST",
url: url,
data: params,
// dataType: "json", //有的時(shí)候jsonp也是一個(gè)選擇
crossDomain: true,
success: function (data) {
},
error: function (e) {
},
complete: function (e) {
},
beforeSend: function (xhr) {
}
});
}
}
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:網(wǎng)絡(luò)轉(zhuǎn)載