一:简介
为什么会出现跨域问题?
受同源策略影响,不同域名之间不可以进行访问。同源策略(Same-Origin Policy)。所谓的 同源 是指域名、协议、端口号 相同。不同的客户端脚本(JavaScript,ActionScript)在没有授权的情况下,不能读取对方资源。简单来说,浏览器允许包含在页面A的脚本访问第二个页面B的数据资源,这一切是建立在A和B页面是同源的基础上。
普通ajax跨域请求,在服务器端不会有任何问题,只是服务端响应数据返回给浏览器的时候,浏览器根据响应头的Access-Control-Allow-Origin字段的值来判断是否有权限获取数据,一般情况下,服务器端如果没有在这个字段做特殊处理的话,跨域是没有权限访问的,所以响应数据被浏览器给拦截了,所以在ajax回调函数里是获取不到数据的
目前比较常见的Jsonp跨域,实际上是创建了一个script标签,因为script跨域时没有限制。如 <script src="http://www.baidu.com"></script> 就会在script里面返回百度的首页内容。
二:CORS原理
CORS(Cross-Origin-Resource Sharing,跨院资源共享)是一种允许多种资源(图片,Css文字,Javascript等)在一个Web页面请求域之外的另一个域的资源的机制。 跨域资源共享这种机制让Web应用服务器支持跨站访问控制,从而使得安全的进行跨站数据传输成为了可能。
三:XMLHttpRequest使用POST跨域请求MVC
JQuery写法
$(function () { var xhr = new XMLHttpRequest(); //相应返回的数据格式 xhr.responseText = "text"; //创建请求 xhr.open("POST", "http://wang.xiaoyaodijun.com/Home/Get"); //的默认值与具体发送的数据类型有关,必须在open()方法之后【普通的表单提交的格式】 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;"); xhr.onreadystatechange = function () { console.log(xhr.responseText); }; xhr.onload = function (msg) { console.log(msg); } xhr.onerror = function (msg) { console.log(msg); } //发送参数 xhr.send("name=jexus&address=www.xiaoyaodijun.com"); });
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> <system.webServer>
写到这,可以跨域请求,但是接受不到数据,提示:已拦截跨源请求:同源策略禁止读取位于 http://wang.xiaoyaodijun.com/Home/Get 的远程资源。(原因:CORS 头缺少 'Access-Control-Allow-Origin')
在Global.asax文件中添加滤器,
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); RouteConfig.RegisterRoutes(RouteTable.Routes); //跨域设置 GlobalFilters.Filters.Add(new AllowOriginAttribute()); }
//AttributeTargets.Class过滤类,AttributeTargets.Method过滤方法 [AttributeUsage(AttributeTargets.Method, AllowMultiple = true, Inherited = false)] public class AllowOriginAttribute : FilterAttribute, IActionFilter { public void OnActionExecuting(ActionExecutingContext filterContext) { } public void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Response.AppendHeader("Access-Control-Allow-Origin", "*"); } }
四:XMLHttpRequest使用POST跨域请求WebApi
同样需要在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> <system.webServer>
从NewGet中添加Microsoft.AspNet.WebApi.Core类库文件
修改WebApiConfig类
public static void Register(HttpConfiguration config) { // Web API 配置和服务 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); // Web API 路由 config.MapHttpAttributeRoutes(); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); }
Jquery请求
<script> $(function () { var xhr = new XMLHttpRequest(); //相应返回的数据格式 xhr.responseText = "text"; //创建请求 xhr.open("POST", "http://xiaoyaodijun.com/api/home/GetName"); //的默认值与具体发送的数据类型有关,必须在open()方法之后【普通的表单提交的格式】 xhr.setRequestHeader("Content-Type", "application/json"); xhr.onreadystatechange = function () { console.log(xhr.responseText); }; xhr.onload = function (msg) { console.log(msg); } xhr.onerror = function (msg) { console.log(msg); } var p={Name:"123",Age:10,Address:"北京朝阳"} xhr.send(JSON.stringify(p)); }); </script>
其他跨域类文章:https://www.cnblogs.com/zhangcybb/p/6594991.html