跨域(jsonp cors)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨域(jsonp cors)相关的知识,希望对你有一定的参考价值。

同源策略它是由NetScape提出的一个著名的安全策略。

浏览器执行js,会检查它属于哪个页面,如果不是同源页面,不会被执行。

由于浏览器的同源策略,只要发送请求url与页面地址有不同的即为跨域。只要协议、域名、端口任何一个不同,就是不同的域。
 
常见的解决方案有:
 jsonp
 跨域资源共享(CORS)
 使用html5的window.postMessage
 通过修改document.domain 
 使用window.name
 
1.jsonp 
     jsonp 全称是JSON with Padding,是为了解决跨域请求资源而产生的解决方案,是一种依靠开发人员创造出的一种非官方跨域数据交互协议
     利用了<script>标签可以链接到不同源的js脚本,来到达跨域目的.(js脚本、css样式 、图片可以与本身页面不同源。)
  <!-- js文件载入成功后会执行我们在url参数中指定的函数,
    并且会把我们需要的json数据作为参数传入。所以jsonp是需要服务器端的页面进行相应的配合的。 -->
    <script type="text/javascript">
        function callback(jsondata) {
            console.log(jsondata);
        }
    </script>
    <script src="http://localhost:5000/api/test/get/callback?callback=callback"></script>
通过ajax调用实现
  $(function () {
            $("#btn").on("click", function () {
                $.ajax({
                    url: "http://localhost:5000/api/test/get/successCallback",
                    dataType: ‘jsonp‘,
                    jsonp: ‘mycallback‘,
                    jsonpCallback: ‘successCallback‘,
                    success: function (data) {
                        $(‘ul li‘).remove();
                        var ul = $("#ul");
                        for (var index = 0; index < data.length; index++) {
                            var element = data[index];
                            ul.append("<li>" + element + "</li>");

                        }
                    },
                    error: function(err){
                        console.log(‘error‘);
                        console.log(err.status);
                    }
                    
                });
            })
        });
?优点:可以实现跨域,兼容性好,回调函数在本地处理
?缺点:只支持get;需要在服务器端增加callback处理;出错,不会有状态码。
 
2.CORS
跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。

跨域资源共享标准( cross-origin sharing standard )允许在下列场景中使用跨域 HTTP 请求:

  • 前文提到的由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
  • Web 字体 (CSS 中通过 @font-face 使用跨域字体资源), 因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
  • WebGL 贴图
  • 使用 drawImage 将 Images/video 画面绘制到 canvas
  • 样式表(使用 CSSOM)
  • Scripts (未处理的异常)

需要在服务器端进行设置,以 .netCore为例:

 public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();

            services.AddCors(options => options.AddPolicy("AllowDomain",
            builder =>
            {
                builder.WithOrigins("*").AllowAnyMethod().AllowAnyHeader();
            }));

        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
             app.UseCors("AllowDomain");
            loggerFactory.AddConsole(Configuration.GetSection("Logging"));
            loggerFactory.AddDebug();
            app.UseMvc();
        }

 

   1.简单请求

      使用GET,HEAD,POST(Content-Type 为 text/plain  multipart/form-data  application/x-www-form-urlencoded)

      请求过程如下图

 

技术分享
代码:
  $("#simplebtnpost").on("click", function () {
                $.ajax({
                    type: "post",
                    data:{name:‘1111‘},
                    url: "http://localhost:5000/api/test/post",
                    success: function (datas) {
                        $(‘ul‘).empty();
                        $.each(datas, function (element) {
                            $(‘ul‘).append("<li>" + datas[element] + "</li>");
                        });

                    }
                });
            })

   2.预检请求

     与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS  方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。

当请求满足下述任一条件时,即应首先发送预检请求:

  • 使用了下面任一 HTTP 方法:PUT;DELETE;CONNECT;OPTIONS;TRACE;PATCH
  • 人为设置了对 CORS 安全的首部字段集合之外的其他首部字段。该集合为:Accept;Accept-Language;Content-Language;Content-Type (but note the additional requirements below);DPR;Downlink;Save-Data;Viewport-Width;Width
  •  Content-Type 的值不属于下列之一:;application/x-www-form-urlencoded;multipart/form-data;text/plain

请求过程:

技术分享

 代码:
            $("#btnput").on("click", function () {
                $.ajax({
                    type: "put",
                    url: "http://localhost:5000/api/test/put",
                    data: {
                        name: ‘测试‘,
                    },
                    dataType: "json",
                    ContentType: "application/json",
                    beforeSend: function (request) {
                        request.setRequestHeader("Content-type",
                            "application/json; charset=utf-8");
                    },
                    success: function (datas) {
                        $(‘ul‘).empty();
                        $.each(datas, function (element) {
                            $(‘ul‘).append("<li>" + datas[element] + "</li>");
                        });

                    }
                });
            })

 

Access-Control-Allow-Origin

响应首部中可以携带一个 Access-Control-Allow-Origin 字段,其语法如下:

Access-Control-Allow-Origin: <origin> | *

Access-Control-Allow-Methods

Access-Control-Allow-Methods 首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。

Access-Control-Allow-Methods: <method>[, <method>]*

Access-Control-Allow-Headers

Access-Control-Allow-Headers 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。

Access-Control-Allow-Headers: <field-name>[, <field-name>]*

 

Access-Control-Allow-Credentials

Access-Control-Allow-Credentials 首部字段用于预检请求的响应,表明服务器是否允许 credentials 标志设置为 true 的请求。

Credentials可以是 cookies, authorization headers 或 TLS client certificates.

Access-Control-Allow-Credentials: true

 

Access-Control-Expose-Headers

Access-Control-Expose-Headers 首部字段指定了服务端允许的首部字段集合。(默认情况是以下六种简单响应首部(simple response headers)):cache-control,

content-language,Content-Type,Expires,Last-Modified,Pragma)

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 

 

以上是关于跨域(jsonp cors)的主要内容,如果未能解决你的问题,请参考以下文章

JSONP跨域和CORS跨域的区别

AJAX跨域调用相关知识-CORS和JSONP

Ajax跨域:jsonp还是CORS

跨域 JSONP, CORS

跨域的问题(jsonp和cors)

面试整理跨域:jsonp与CORS