如何使用 jQuery 发送跨域 AJAX 请求
本文发布于 7 年前,部分内容可能已经失去参考价值。
在本教程中,我解释了如何使用 jQuery 和 ASP.NET 发送跨域 AJAX 请求,PHP 开发者请参考此文。
跨域 AJAX 请求有两种方式:
1). 使用 JSONP
2). 使用 CORS(跨源资源共享)
1). 使用 JSONP
我们可以使用 JSONP 发送跨域 AJAX 请求。下面是简单的 JSONP 请求:
$.ajax({ url : "http://xoyozo.net/cross-domain-cors/jsonp.aspx", dataType:"jsonp", jsonp:"mycallback", success:function(data) { alert("Name:"+data.name+"nage:"+data.age+"nlocation:"+data.location); } });
jsonp.aspx 响应是:
mycallback({"name": "Ravishanker", "age": 32, "location": "India"})
当 JSONP 请求成功时,调用 mycallback 函数。
这能在所有浏览器中正常运行,但问题是:JSONP 只支持 GET 方法,不支持 POST 方法。
2). 使用 CORS(跨源资源共享)
出于安全考虑,浏览器不允许跨域 AJAX 请求。仅当服务器指定相同的源安全策略时,才允许跨域请求。常见的异常警告:
You can not send Cross Domain AJAX requests:
XMLHttpRequest cannot load. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin is therefore not allowed access.
阅读更多关于跨源资源共享(CORS):Wiki
要启用 CORS,您需要在服务器中指定以下 HTTP 标头。
Access-Control-Allow-Origin – 允许跨域请求的域的名称。 * 表示允许所有域。
Access-Control-Allow-Methods – 在请求期间可以使用 HTTP 方法的列表。
Access-Control-Allow-Headers – 可以在请求期间使用 HTTP 头列表。
在 ASP.NET 中,您可以使用以下代码设置标头:
Response.AddHeader("Access-Control-Allow-Origin", "*"); Response.AddHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS"); Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Content-Range, Content-Disposition, Content-Description");
CORS 在所有最新的浏览器中正常工作,但不支持 IE8 和 IE9,异常:
You can not send Cross Domain AJAX requests: No Transport
IE8、IE9 使用 window.XDomainRequest 处理 AJAX 请求。我们可以使用这个 jQuery 插件:
https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest
为了在 IE 中使用 XDomainRequest,请求必须是:
a). GET 或 POST
数据必须以 Content-Type 为 text/plain 的方式发送
b). HTTP 或 HTTPS
协议必须与调用页面相同
c). 异步
具体步骤:
第一步:在 <head> 中添加脚本
<script type='text/javascript' src="http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest.min.js"></script>
第二步:在 $.ajax 请求中设置 contentType 值 text/plain。
var contentType ="application/x-www-form-urlencoded; charset=utf-8"; if(window.XDomainRequest) // for IE8,IE9 contentType = "text/plain"; $.ajax({ url: "http://xoyozo.net/cross-domain-cors/post.aspx", data: "name=Ravi&age=12", type: "POST", dataType: "json", contentType: contentType, success: function(data) { alert("Data from Server" + JSON.stringify(data)); }, error: function(jqXHR, textStatus, errorThrown) { alert("You can not send Cross Domain AJAX requests: " + errorThrown); } });
post.aspx 源码:
Response.AddHeader("Access-Control-Allow-Origin", "*"); Response.AddHeader("Access-Control-Allow-Methods", "GET, PUT, POST, DELETE, OPTIONS"); Response.AddHeader("Access-Control-Allow-Headers", "Content-Type, Content-Range, Content-Disposition, Content-Description"); NameValueCollection nvc = new NameValueCollection(); // nvc.Add(Request.QueryString); nvc.Add(Request.Form); if (nvc.Count == 0) { string data = System.Text.Encoding.Default.GetString(Request.BinaryRead(Request.TotalBytes)); nvc = HttpUtility.ParseQueryString(data); } string name = nvc["name"]; int age = Convert.ToInt32(nvc["age"]);