• WebApi 跨域解决方案 --CORS


    跨站HTTP请求(Cross-site HTTP request)是指发起请求的资源所在域不同于请求指向的资源所在域的HTTP请求。

    比如说,我在Web网站A(www.a.com)中通过<img>标签引入了B站的资源(www.b.com/images/1.jpg),那么A站会向B站发起一个跨站请求。

    这种图片资源的跨站请求是被允许的,类似的跨站请求还有CSS文件,JavaScript文件等。

    但是如果是在脚本中发起HTTP请求,出于安全考虑,会被浏览器限制。比如,使用 XMLHttpRequest 对象发起 HTTP 请求就必须遵守 同源策略

    所谓“同源策略”是指Web应用程序只能使用 XMLHttpRequest 对象向发起源所在域内发起HTTP请求,这个请求源和请求对象必须在一个域内。

    举例来说,http://www.a.com,这个网址的协议是http,域名是www.a.com,端口默认是80。那么以下是它的同源情况:

    • http://www.a.com/index.html 同源
    • https://www.a.com/a.html 不同源(协议不同)
    • http://service.a.com/testService/test 不同源(域名不同)
    • http://www.b.com/index.html 不同源(域名不同)
    • http://www.a.com:8080/index.html 不同源(端口不同)

    为了开发出更强大,更丰富的Web应用,跨域请求是很常见的,那么如何在不舍弃安全的情况下进行跨域请求呢?

    W3C推荐了一种新的机制,即跨源资源共享(Cross-Origin Resource Sharing (CORS))。

    跨源资源共享(CORS)是通过客户端+服务端协作声明的方式来确保请求安全的。服务端会在HTTP请求头中增加一系列HTTP请求参数(例如Access-Control-Allow-Origin等),来限制哪些域的请求和哪些请求类型可以接受,而客户端在发起请求时必须声明自己的源(Orgin),否则服务器将不予处理,如果客户端不作声明,请求甚至会被浏览器直接拦截都到不了服务端。服务端收到HTTP请求后会进行域的比较,只有同域的请求才会处理。

    一个使用CORS实现跨域请求的示例:

    客户端:

    function getHello() {
        var xhr = new XMLHttpRequest();
        xhr.open("post", "http://b.example.com/Test.ashx", true);
        xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");   
        // 声明请求源
        xhr.setRequestHeader("Origin", "http://a.example.com");
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                var responseText = xhr.responseText;
                console.info(responseText);
            }
        }
        xhr.send();
    }
    

    服务端:

    public class Test : IHttpHandler
       {
     
           public void ProcessRequest(HttpContext context)
           {
               context.Response.ContentType = "text/plain";
               // 声明接受所有域的请求
               context.Response.AddHeader("Access-Control-Allow-Origin", "*");
               context.Response.Write("Hello World");
           }
     
           public bool IsReusable
           {
               get
               {
                   return false;
               }
           }
       }
    

      

    在Web API中启用跨域访问

    CORS是服务端和客户端协作声明来确保请求安全的,因此,如果需要在Web API中启用CORS也需要进行相应配置。好在微软的ASP.NET团队提供了官方的支持跨域的解决方案,只需要在NuGet中添加即可。

    然后在App_Start/WebApiConfig.cs进行如下配置即可实现跨域访问:

    public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
                // Web API 配置和服务
                // 将 Web API 配置为仅使用不记名令牌身份验证。
                config.SuppressDefaultHostAuthentication();
                config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
     
                // Web API 路由
                config.MapHttpAttributeRoutes();
     
                config.Routes.MapHttpRoute(
                    name: "DefaultApi",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional }
                );
     
                // 允许Web API跨域访问
                EnableCrossSiteRequests(config);
     
                config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
            }
     
            private static void EnableCrossSiteRequests(HttpConfiguration config) {
                var cors = new EnableCorsAttribute(
                  origins: "*",
                  headers: "*",
                  methods: "*"
                  );
                config.EnableCors(cors);
            }
        }
    

      

    由于IE10以下浏览器不支持CORS,所以目前在国内CORS并不是主流的跨域解决方案,但是随着windows 10的发布,IE的逐渐衰落,可以预见,在不远的将来CORS将成为跨域的标准解决方案之一。

    demo下载(bd36)

    参考资料:

    https://www.w3.org/TR/cors/

    http://www.ruanyifeng.com/blog/2016/04/cors.html

    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

    转自 https://www.cnblogs.com/colder/p/5704131.html

  • 相关阅读:
    TSINGSEE青犀视频编译中通过Golang代码修改Linux服务的ulimit的实现
    为什么说全球疫情的刺激,加快了AI视频智能分析技术的需求?
    EasyPlayer.JS播放录像报错视频文件损坏且播放终止怎么处理?
    TSINGSEE青犀视频开发AI智能分析采用c++中文编码出现乱码问题是由什么导致的
    EasyPlayerJS开发环境出现错误信息并且不展示播放器问题优化
    EasyNVR开发中VLC Player如何将日志输入到文件中以及设置以TCP方式拉取RTSP流
    车牌识别在智慧交通中的重要作用
    树型结构数据,求某结点的所有父结点的自定义函数
    一条有意思的SQL语句分析
    树形数据显示SQL示例代码(在ms sql 2000 DBMS中调试通过)
  • 原文地址:https://www.cnblogs.com/zhangxiaoxia/p/10881493.html
Copyright © 2020-2023  润新知