跨域问题小结

软件实训项目遇到了一些疑惑,顺便整理整理概念和思路。

 
0.两大请求类型
  浏览器将CORS请求分成两类
    简单请求(simple request)和非简单请求(not-so-simple request)。
  只要同时满足以下两大条件,就属于简单请求。
     (1) 请求方法是以下三种方法之一:
      HEAD
      GET
      POST
     (2)HTTP的头信息不超出以下几种字段:
      Accept
      Accept-Language
      Content-Language
      Last-Event-ID
      Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain
  凡是不同时满足上面两个条件,就属于非简单请求。
  浏览器对这两种请求的处理,是不一样的。
  -----摘自 阮一峰老师 博客
 
1.跨域三条件(三个作为充分条件,必须满足全部)
  1、浏览器限制
  2、跨域行为(域名,端口,协议不一样都是跨域)
    域名[主域名与子域名也算]不同
    端口不同
    协议不同
    特注:Ip与域名之间网络交互,也属于跨域,如:123.23.23.12 和 www.a.com
  3、XHR(XMLHttpRequest请求)
 
2.解决方案
  网上最多讲述的就是方案,但讲原理的甚少;推荐看阮一峰老师的文章去。
  [1]从浏览器出发,允许浏览器跨域。
  [2]从XHR(XMLHttpRequest)出发。(仅暂列出三点,Google一下,方案还有很多)
    A.JSONP:使用方式就不赘述了,但是要注意JSONP只支持GET请求,不支持POST请求。
    B.服务器中间代理。将要请求的目标接口在需要使用方项目处封装为接口响应给客户端。
    C.开放需要使用方项目自身的跨域网络方案。[针对接口受使用方控制]
      ①Spring注解@CrossOrigin实现细化到某个或者某些url(action)映射级别:
      ②[常用]手动编程设置,可以写成过滤器一类的。以下是常见设置:  
      set:header('Access-Control-Allow-Origin:*');//允许所有来源访问,* 可以换为origin或者referer:req.getHeader("Origin")更安全一点,有兴趣可以探究一下origin与referer的区别~
      set:header('Access-Control-Allow-Method:POST,GET');//允许访问的方式
      set:header('Access-Control-Allow-Credentials:true');//服务器端是否允许携带cookie    
      set:header("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, Authorization, token, Origin");//request允许携带的header
      set:header("Access-Control-Max-Age", "3600");
 
3.哪些情况是跨域?
  http://www.123.com/index.html 调用 http://www.123.com/server.php (非跨域)
  http://www.123.com/index.html 调用 http://www.456.com/server.php (主域名不同:123/456,跨域)
  http://abc.123.com/index.html 调用 http://def.123.com/server.php (子域名不同:abc/def,跨域)
  http://www.123.com:8080/index.html 调用 http://www.123.com:8081/server.php (端口不同:8080/8081,跨域)
  http://www.123.com/index.html 调用 https://www.123.com/server.php (协议不同:http/https,跨域)
  注:localhost和127.0.0.1虽然都指向本机,但也属于跨域。
 
4.概念区分
  0.热身问题(见图)
  1.浏览器直接输入URL|img(javascript).src|link(a;base).href:不涉及跨域,且:属用户已知又主动
  2.当前网站网页下Ajax请求其他链接:可能涉及跨域,且:用户未知又被动,防止盗传用户数据到其他网站
  3.微信小程序请求我方服务器,是否涉及跨域呢?
    微信小程序request方法不需要考虑跨域访问问题,因为:微信小程序的做法是由微信官方的服务器取访问我方的服务器,所以实际的“跨域问题”已经在我们的小程序与微信后台交流的时候解决了
    微信官方对应文档:https://developers.weixin.qq.com/miniprogram/dev/api/network/request/wx.request.html
    另外,需注意:微信小程序wx.request不支持获取我方响应给小程序的response.Cookie/Session和Header机制;
    但小程序支持发起请求时携带cookie或者控制header。小程序(客户端):要维持会话就需要自己来保存cookie,并且请求的时候加上cookie;我方数据端(服务器端):原自动返回的cookie放在header中已经不行了,服务器端需要额外为小程序显式返回JSESSIONID,保障小程序能维护会话
    如何维护,详见这位博主的博客:微信小程序设置cookie
  4.Chrome下的网络调试神器Postman所发的网络请求是否存在跨域问题?
    答案是:Postman可能申请了Chrome插件的ajax跨域权限,不存在跨域问题
  5.不同的ajax请求对象,如何保持会话Session/Cookie的问题[非跨域问题]

   

  如果ajax对象不主动设置xml.withCredentials=true(携带Cookie),则Chrome控制台每new XMLHttpRequest()一次ajax请求对象,就是新建一次会话

  6.iframe跨域问题

    主要分三类:1、不跨域时   2、主域相同、但子域不同时   3、主域不同​

    详见博文iFrame跨域解决办法

 
5.JavaScript提供的Ajax请求对象到底都提供了哪些接口?
  见博文:JavaScript之Ajax Util 文末处。
 
6.参考文献
 
 
7.英文备注
  Credentials:凭证,凭据
原文地址:https://www.cnblogs.com/johnnyzen/p/9930295.html