CORS-跨域资源共享 解决跨域问题

时间:2022-09-09 17:57:02

1.什么是跨域?

  a.test.com 和 b.test.com 是两个不同的域,而处于安全机制考虑,JS只能访问与所在页面同一个域(相同协议、域名、端口)的内容,但是我们在项目开发时,经常遇到一个页面的js代码,需要去访问另一个服务器上的接口,包括GET,POST,PUT等不同形式请求,这就出现了跨域问题。

CORS-跨域资源共享 解决跨域问题

2.解决跨域的几种方法。

  通过实际项目中涉及到的和网上看到别人用过的,总结一下大概有以下几种方法:

  1). document.domain

    在主域相同的时候才能使用。

  2). iframe

    这种方式已经很少见到了,很不优雅,很难控制。

  3). JSONP

    这种方式应该是有一定的能力处理跨域请求的,但是缺点也十分明显,因为原理是动态创建script标签,通过回调来获取数据,那么就是说它只能处理GET请求。而且对于请求失败的error处理也不好。

  4). web socket

    H5 新增加的一种浏览器的API。只有在支持web socket协议的服务器上才能正常工作。

  var url='ws://www.baidu.com';  //http->ws; https->wss 

  if ("WebSocket" in window) {
    console.log("WebSocket works...");
    var ws = new WebSocket(url);
    ws.onopen = function() {
      // Web Socket is connected, send data using send()
      var msg = '{"key": "test","group": "A"}';
      ws.send(msg);
      console.log("Request to open a connection... Message sent...");

    };
    ws.onmessage = function(evt) {
      var data = evt.data;
      // console.log("Message received, and it's...");
      console.log(data);
    };
    ws.onclose = function(e) {
      // websocket is closed.
      console.log("Connection is closed...");
      //console.log(e);
      connect();
    };
    ws.onerror = function(e){
      // websocket is error.
      console.log("Connection is error...");
      //console.log(e);
    }
  } else {
    // The browser doesn't support WebSocket
    console.warn("WebSocket NOT supported by your Browser...");
  }

  5).CORS

    这么多解决方法中目前最方便有效的就是这种,CORS。

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing),它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源的限制。

  6).在开发中经常用来解决本地跨域的一种方法是配置nginx,再转发到线上或者测试服务器。不知道这种算不算一种方法。

   http {

    server {         

      listen          80;         

      server_name      w.dev.test.com w.test.com;         

       location ~ ^/(api|action|avatar|financing|files)/{

        if ($host = "w.test.com"){

          proxy_pass "https://www.test.com";

        }

        if ($host = "w.dev.test.com"){

          proxy_pass "http://dev.test.com";

        }

      }

      location /{ ... }

    }

  }

3.CORS 详解:

  CORS实现起来很简单,但是需要浏览器和服务器同时支持,也就是说服务器需要配置允许你跨域请求,浏览器也需要支持你能够跨域去请求资源。目前大部分浏览器都能够支持。

  1). 服务器端配置:

    Access-Control-Allow-Origin: <origin> | * // 授权的源控制

    Access-Control-Max-Age: <delta-seconds> // 授权的时间

    Access-Control-Allow-Credentials: true | false // 控制是否开启与Ajax的Cookie提交方式

    Access-Control-Allow-Methods: <method>[, <method>]* // 允许请求的HTTP Method

    Access-Control-Allow-Headers: <field-name>[, <field-name>]* // 控制哪些header能发送真正的请求

    CORS-跨域资源共享 解决跨域问题

    response headers中与CORS请求相关的字段,都以Access-Control-开头。

    (1)Access-Control-Allow-Origin 该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

    (2)Access-Control-Allow-Credentials 该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

    (3)Access-Control-Allow-Headers 如果浏览器请求包括Access-Control-Request-Headers字段,则Access-Control-Allow-Headers字段是必需的。它也是一个逗号分隔的字符串,表明服务器支持的所有头信息字段。

    (4)Access-Control-Allow-Methods 该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。测试中发现,如果浏览器请求中没有Access-Control-Request-Method字段,此字段可不设置。

    (5)Access-Control-Max-Age 该字段可选,用来指定本次预检请求的有效期,单位为秒。

  ***需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

  2). 前端

  如果前端不做任何特殊设置,正常请求跨域的域名接口是可以的,但是只能是GET,且不带有cookie。

  如果想要在request headers中带有cookie就要进行特殊的设置。

  jQuery:

    $.ajax("www.cros.com/api/data", {

      type: "GET",

      xhrFields: {

        withCredentials: true

      },

      success: function(data, status, xhr) {}

    });

  angularJs:

    $http.post(url, {withCredentials: true, ...})

    // 或者

    $http({withCredentials: true, ...}).post(...)

    // 或者

    .config(function ($httpProvider) {

      $httpProvider.defaults.withCredentials = true;

    }

  经过测试法相,jQuery中无论是GET请求还是POST请求,在请求头中是不会加上Access-Control-Request-Headers字段的,也就是说这样jQuery不需要服务器设置Access-Control-Allow-Headers。可以看到只有Host显示是跨域请求,其他的和同域没什么区别。

CORS-跨域资源共享 解决跨域问题

但是在angularJs中是不一样的,GET请求基本差不多

CORS-跨域资源共享 解决跨域问题

但是POST请求是会加上 Access-Control-Allow-Methods和Access-Control-Allow-Headers。

CORS-跨域资源共享 解决跨域问题

这时如果服务器没有设置Access-Control-Allow-Headers,就会请求失败。

CORS-跨域资源共享 解决跨域问题

参考:http://www.cnblogs.com/JChen666/p/3399951.html

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

     https://my.oschina.net/blogshi/blog/303758

CORS-跨域资源共享 解决跨域问题的更多相关文章

  1. CORS(跨域资源共享)跨域问题及解决

    当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Control-Allow-Origin.肯 ...

  2. CORS跨域资源共享

    CORS(跨域资源共享)跨域问题及解决 当使用ajax跨域请求时,浏览器报错:XmlHttpRequest error: Origin null is not allowed by Access-Co ...

  3. 跨域解决方案 - 跨域资源共享cors

    目录 1. cors 介绍 2. 原理 3. cors 解决跨域 4. 自定义HTTP 头部字段解决跨域 5. 代码演示 5. 参考链接 1. cors 介绍 cors 说的是一个机制,其实相当于一个 ...

  4. 阿里P7架构师是如何解决跨域问题的!你有遇到吗?

    现在越来越多的项目就算是一个管理后端也偏向于使用前后端分离的部署方式去做,为了顺应时代的潮流,一前后端分离就产生了跨域问题,所以许多同学把跨域和前后端分离项目联系在了一起,其实跨域产生的原因并不是前后 ...

  5. 前端如何使用proxyTable和nginx解决跨域问题

    最近经常遇到跨域的问题,有时候问题虽然解决了,但是还是会有些模棱两可概念不清,于是在网上看了一些教程结合实际使用,做个笔记. 1.跨域原因 浏览器的限制 跨域(协议/域名/端口的不同) XMLHttp ...

  6. CORS(跨站资源共享)介绍

    起因 有同学在nginx站点配置中加了一行Access-Control-Allow-Origin *,导致微信中业务数据异常,抓包看http头有两个Access-Control-Allow-Origi ...

  7. 跨域问题解决方式&lpar;HttpClient安全跨域 &amp&semi;amp&semi; jsonp跨域&rpar;

    1 错误场景 今天要把项目部署到外网的时候,出现了这种问题, 我把两个项目放到自己本机的tomcat下, 进行代码调试, 执行 都没有问题的, 一旦把我须要调用接口的项目B放到其它的server上, ...

  8. PhoneGap开发跨平台移动APP - 解决跨域资源共享

    解决跨域资源共享 一.WebApi解决跨域资源共享. 开发中选择WebApi来作为服务端的数据接口,由于使用PhoneGap,就需要通过js来获取远程远程数据服务器的数据,由于同源策略的限制,这就涉及 ...

  9. &lbrack;CORS:跨域资源共享&rsqb; 同源策略与JSONP

    Web API普遍采用面向资源的REST架构,将浏览器最终执行上下文的JavaScript应用Web API消费者的重要组成部分."同源策略"限制了JavaScript的跨站点调用 ...

随机推荐

  1. POJ----&lpar;3974 &rpar;Palindrome &lbrack;最长回文串&rsqb;

    Time Limit: 15000MS   Memory Limit: 65536K Total Submissions: 5121   Accepted: 1834 Description Andy ...

  2. Linux下使用GDB调试程序

    问题描述:          Linux下使用GDB调试程序 问题解决:          (1)生成调试文件 注:         使用命令   gdb IOStream.c   -o IOStre ...

  3. Floyd最小环

    本文转自这里 最小环:从一个点出发,经过一条简单路径回到起点成为环.图的最小环就是所有环中长度最小的. 怎样求最小环呢? 1传统的解决方法(dijkstra):        任意一个最小环环的权值, ...

  4. 创建git密钥的时候提示 too many arguments

    这个时候只要这样做就ok了, 给邮箱包两层引号,如下: " 'zhangsanfeng@qq.com' " 妥妥的!

  5. Java模拟http上传文件请求(HttpURLConnection&comma;HttpClient4&period;4&comma;RestTemplate)

    先上代码: public void uploadToUrl(String fileId, String fileSetId, String formUrl) throws Throwable { St ...

  6. 安装linux的关键步骤

  7. 分布式定时任务框架——python定时任务框架APScheduler扩展

    http://bbs.7boo.org/forum.php?mod=viewthread&tid=14546 如果将定时任务部署在一台服务器上,那么这个定时任务就是整个系统的单点,这台服务器出 ...

  8. jsp的九大内置对象及作用

    内置对象名          类型                                   request           HttpServletRequest             ...

  9. 算法笔记&lowbar;220&colon;猜算式(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 看下面的算式: □□ x □□ = □□ x □□□ 它表示:两个两位数相乘等于一个两位数乘以一个 三位数. 如果没有限定条件,这样的例子很多. 但 ...

  10. 明明白白AOP

    引子: AOP(面向方面编程:Aspect Oriented Programing)和IoC一样是Spring容器的内核,声明式事务的功能在此基础上开花结果.但是AOP和OOP差别较大,要很好地理解这 ...