CORS跨域

一:简介

为什么会出现跨域问题?

受同源策略影响,不同域名之间不可以进行访问。同源策略(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

原文地址:https://www.cnblogs.com/xiaoyaodijun/p/7070038.html