下面是详细讲解“jQuery.ajax 跨域请求webapi设置headers的解决方案”的完整攻略:
背景
在Web开发中,由于安全限制,浏览器禁止跨域访问,因此跨域请求时需要采取一定的措施,在服务器端进行一定的设置。而在使用jQuery进行跨域请求时,如果需要设置请求头(headers),就需要特别注意。
解决方案
方案一:在后台进行修改
如果对后台进行修改,开放一定的请求头,就可以解决问题。
具体方法如下:
- 在 WebAPI 中的
WebApiConfig
类中添加如下代码:
public static void Register(HttpConfiguration config)
{
// 只允许指定的头字段
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
// 其他配置
}
在此代码中,*
表示允许所有源、所有头和所有方法。
- 在 WebAPI 中支持 OPTIONS 请求
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
}
此代码中,首先判断请求头是否包含“Origin”,如果包含并且请求方法是“OPTIONS”,则请求前通过 Response.Flush()
先响应,这样就可以防止 OPTIONS 请求发往 WebAPI 方法了。
方案二:使用JSONP跨域请求
JSONP 可以解决跨域的问题,其实现原理是在请求时动态产生一个 <script>
标签,服务端返回一段JavaScript代码,再将其追加到网页中。这种做法可以解决浏览器对于跨域请求不支持 cookie 的问题,而且入门还比较简单。
具体方法如下:
- 在JS代码中添加:
$.ajax({
url: "http://www.server.com/getdata.js",
dataType: "jsonp",
// 定义 JSONP 的回调名称
jsonp: "callback",
// 服务端返回值接收方法的名称
jsonpCallback: "dealResponse",
success: function (result) {
console.log(result);
}
});
function dealResponse(data) {
console.log(data);
}
- 在 ASP.NET WebAPI 项目中添加一个控制器:
public class GetJsonpDataController : ApiController
{
[HttpGet, ActionName("Get"), AllowAnonymous]
public string Get(string callback)
{
return string.Format("{0}({1});", callback, "{'name': '张三', 'age': '18'}");
}
}
在此代码中,将结果字符串用 {callback}({result string});
的格式返回,浏览器会自动分析 callback
参数,然后将 {result string}
以 callback
为函数名包裹在一个 script 标签里远程调用。
示例说明
这里给出两个示例进行说明:
示例一:WebAPI 请求header无效问题
在前端页面中使用 jQuery.ajax 进行跨域请求 WebAPI 接口时,如果想要在 headers 中加入某个参数,其实大家一般是采取如下代码:
$.ajax({
url: "http://www.server.com/api/getdata",
type: "POST",
dataType: "json",
data: JSON.stringify({}),
async: true,
headers: {
"Token":"xxxxxxx"
},
success: function(result){},
error: function(){alert("Error");}
});
然而,这种方式在部分浏览器中可能会产生错误,导致 header 参数无法传送到 WebAPI 的问题。原因是:jQuery ajax 在 POST 跨域请求时不管在 headers 中设置什么参数,服务端都无法读取,但是在GET跨域请求时一切正常。
解决办法就是在服务端 WebAPI 中添加如下代码,即可解决问题:
protected void Application_BeginRequest(object sender, EventArgs e)
{
if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS")
{
Response.Flush();
}
var origin = Request.Headers["Origin"];
if (Request.Headers.AllKeys.Contains("Origin"))
{
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Origin", origin);
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Headers", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Methods", "*");
HttpContext.Current.Response.AddHeader("Access-Control-Allow-Credentials", "true");
}
}
示例二:jQuery ajax 跨域“丢失”数据问题
假如在 jQuery ajax 跨域请求时,由于调用了原生ajax的调用方式,因此可能会丢失数据。
解决办法就是不要使用原生ajax,而是使用jquery自带的ajax。采用如下代码:
$.ajax({
url: "http://www.server.com/api/getdata",
type: "POST",
dataType: "json",
data: JSON.stringify({}),
async: true,
headers: {
"Token":"xxxxxxx"
},
success: function(result){},
error: function(){alert("Error");}
});
这样就可以使用了!其中,url参数表示调用的远程地址,type指定调用类型(HTTP的get和post等),data则是向远程地址发送的数据。这里的 data 是从一个 JSON 对象里面动态生成的。如果您希望使用常规格式的表单数据,也可以使用 jquery 库中提供的 $.param 函数。同时,headers 指定了一个 HTTP 头部包含数据。最后,Promise对象可以将异步请求的结果返回,使用 then 方法进行处理。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:jQuery.ajax 跨域请求webapi设置headers的解决方案 - Python技术站