![web api 跨域请求,ajax跨域调用webapi web api 跨域请求,ajax跨域调用webapi](https://image.shishitao.com:8440/aHR0cHM6Ly9ia3FzaW1nLmlrYWZhbi5jb20vdXBsb2FkL2NoYXRncHQtcy5wbmc%2FIQ%3D%3D.png?!?w=700&webp=1)
1、跨域问题仅仅发生在Javascript发起AJAX调用,或者Silverlight发起服务调用时,其根本原因是因为浏览器对于这两种请求,所给予的权限是较低的,通常只允许调用本域中的资源,除非目标服务器明确地告知它允许跨域调用。假设我们页面或者应用已在 http://www.test1.com 上了,而我们打算从 http://www.test2.com 请求提取数据。一般情况下,如果我们直接使用 AJAX 来请求将会失败,浏览器也会返回“源不匹配”的错误,"跨域"也就以此由来。
2、什么是跨域呢?
![web api 跨域请求,ajax跨域调用webapi web api 跨域请求,ajax跨域调用webapi](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvNzg0NTU0LzIwMTUwOC83ODQ1NTQtMjAxNTA4MzExNDA1MDA4ODgtNzY3NDg5OTM5LnBuZw%3D%3D.png?w=700&webp=1)
![web api 跨域请求,ajax跨域调用webapi web api 跨域请求,ajax跨域调用webapi](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMyMDE1LmNuYmxvZ3MuY29tL2Jsb2cvNzg0NTU0LzIwMTUwOC83ODQ1NTQtMjAxNTA4MzExNDA3NTAzNzItMTg0MTAwMzYyOS5wbmc%3D.png?w=700&webp=1)
json格式:
{
"message":"获取成功",
"state":"1",
"result":{"name":"工作组1","id":1,"description":"11"}
}
jsonp格式:
callback({
"message":"获取成功",
"state":"1",
"result":{"name":"工作组1","id":1,"description":"11"}
})
看出来区别了吧,在url中callback传到后台的参数是神马callback就是神马,jsonp比json外面有多了一层,callback()。
只需要给全局注册一个JsonCallbackAttribute,就可以判断接口的访问是属于跨域,还是非跨域,正常的返回。
因为我们的接口,可能是用来给 移动端(Android 、IOS)做数据接口,也有可能是给网站用,所以,考虑到可能存在跨域的问题。
GlobalConfiguration.Configuration.Filters.Add(new JsonCallbackAttribute());
![web api 跨域请求,ajax跨域调用webapi web api 跨域请求,ajax跨域调用webapi](https://image.shishitao.com:8440/aHR0cHM6Ly9jb21tb24uY25ibG9ncy5jb20vaW1hZ2VzL2NvcHljb2RlLmdpZg%3D%3D.gif?w=700&webp=1)
public class JsonCallbackAttribute : ActionFilterAttribute
{
private const string CallbackQueryParameter = "callback"; public override void OnActionExecuted(HttpActionExecutedContext context)
{
var callback = string.Empty; if (IsJsonp(out callback))
{
var jsonBuilder = new StringBuilder(callback); jsonBuilder.AppendFormat("({0})", context.Response.Content.ReadAsStringAsync().Result); context.Response.Content = new StringContent(jsonBuilder.ToString());
//context.Response.Content = new StringContent("C(\"a\")");
} base.OnActionExecuted(context);
} private bool IsJsonp(out string callback)
{
callback = System.Web.HttpContext.Current.Request.QueryString[CallbackQueryParameter]; return !string.IsNullOrEmpty(callback);
}
![web api 跨域请求,ajax跨域调用webapi web api 跨域请求,ajax跨域调用webapi](https://image.shishitao.com:8440/aHR0cHM6Ly9jb21tb24uY25ibG9ncy5jb20vaW1hZ2VzL2NvcHljb2RlLmdpZg%3D%3D.gif?w=700&webp=1)
结合下面图片不难开出,请求的地址带回了,callback的参数标识。
当然也可以用解决跨域问题的jQuery插件-jquery-jsonp,有第一种方式的基础,使用jsonp插件也就比较简单了,server端代码无需任何改动。
5、服务端直接修改配置文件,个人认为这种方式好一点,毕竟我们所写的api是对外公开的,安全访问的控制还是要通过其他方法来保证。
针对ASP.NET MVC,只需要在web.config中添加如下的内容即可
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
</customHeaders>
</httpProtocol>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
针对ASP.NET Web API,除了上面这样的设置,还需要添加一个特殊的设计,就是为每个APIController添加一个OPTIONS的方法,但无需返回任何东西。
public string Options()
{
return null; // HTTP 200 response with empty body
}
6、还有用CORS(跨域资源共享,Cross-Origin Resource Sharing)来解决的, CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。
![web api 跨域请求,ajax跨域调用webapi web api 跨域请求,ajax跨域调用webapi](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvMTU5MDk3LzIwMTQwMS8wNjA4MjE1OS1iMWExMDJhM2NlMGU0OWU3ODQxZjc2Njc1MjM2ZTQwOC5wbmc%3D.png?w=700&webp=1)
也可以设置指定的域名,如域名 http://www.test2.com ,那么就允许来自这个域名的请求:
![web api 跨域请求,ajax跨域调用webapi web api 跨域请求,ajax跨域调用webapi](https://image.shishitao.com:8440/aHR0cHM6Ly9pbWFnZXMwLmNuYmxvZ3MuY29tL2Jsb2cvMTU5MDk3LzIwMTQwMS8wNjA4MjIyNy0xMGYyMmM0Zjc1MDk0ZmFlYjc4MjU1NTA5MTk5YWVkNS5wbmc%3D.png?w=700&webp=1)