原文:https://www.cnblogs.com/inconceivable/p/5504732.htmljavascript
一、跨域问题仅仅发生在Javascript发起AJAX调用,或者Silverlight发起服务调用时,其根本缘由是由于浏览器对于这两种请求,所给予的权限是较低的,一般只容许调用本域中的资源,除非目标服务器明确地告知它容许跨域调用。假设咱们页面或者应用已在 http://www.test1.com 上了,而咱们打算从 http://www.test2.com 请求提取数据。通常状况下,若是咱们直接使用 AJAX 来请求将会失败,浏览器也会返回“源不匹配”的错误,"跨域"也就以此由来。html
二、什么是跨域呢?java


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()。jquery
只须要给全局注册一个JsonCallbackAttribute,就能够判断接口的访问是属于跨域,仍是非跨域,正常的返回。git
由于咱们的接口,多是用来给 移动端(Android 、IOS)作数据接口,也有多是给网站用,因此,考虑到可能存在跨域的问题。github
GlobalConfiguration.Configuration.Filters.Add(new JsonCallbackAttribute());
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); }
结合下面图片不难开出,请求的地址带回了,callback的参数标识。web
固然也能够用解决跨域问题的jQuery插件-jquery-jsonp,有第一种方式的基础,使用jsonp插件也就比较简单了,server端代码无需任何改动。json
五、服务端直接修改配置文件,我的认为这种方式好一点,毕竟咱们所写的api是对外公开的,安全访问的控制仍是要经过其余方法来保证。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
}
六、还有用CORS(跨域资源共享,Cross-Origin Resource Sharing)来解决的, CORS定义一种跨域访问的机制,可让AJAX实现跨域访问。CORS 容许一个域上的网络应用向另外一个域提交跨域 AJAX 请求。实现此功能很是简单,只需由服务器发送一个响应标头便可。

也能够设置指定的域名,如域名 http://www.test2.com ,那么就容许来自这个域名的请求:
