如何使用 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"]);

 

xoyozo 8 年前
转载请注明出处
可能相关的内容