前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >跨域访问知多少

跨域访问知多少

作者头像
黑洞代码
发布2021-01-14 15:40:22
1.3K0
发布2021-01-14 15:40:22
举报

什么是跨域

因为浏览器的同源策略导致了跨域,就是浏览器在搞事情。

什么同源策略

浏览器的同源策略,要同源说起。顾名思义,同源就是源头相同,即两个页面的协议、端口和域名都相同,任何一个不满足,都会导致跨域。

下表给出了相对http://www.baibai.com/say/one.html同源检测的示例:

URL

结果

原因

http://www.baibai.com/say/other.html

成功

同一域名,同一文件夹

http://www.baibai.com/say/hi/another.html

成功

同一域名,不同文件夹

https://www.baibai.com/say/oneByOne.html

失败

不同协议 ( https和http )

http://www.baibai.com:81/say/two.html

失败

不同域名 ( news和www )

http://news.baibai.com/say/three.html

失败

不同域名 ( news和www )

跨域如何解决

场景1:基于前端jquery的跨域

如果是一般的ajax请求:

代码语言:javascript
复制
  $.ajax({

     url:'http://news.baibai.com/say/test/testjsonp',

      type :'get',

      dataType :'text',

     success:function(data){

         alert(data);

      },

      error:function(data){

          alert(“error”);

     }       

 });

那么在浏览器中会报错。

如果改用jsonp形式的ajax请求,并且通过get请求的方式传入参数,注意:跨域请求是只能是get请求不能使用post请求。

代码语言:javascript
复制
 <!DOCTYPEhtml>

  <html>

    <head>

    <metacharset="UTF-8">

    <title>Inserttitle here</title>

    <scripttype="text/javascript"src="./js/jquery.js"></script>

    <scripttype="text/javascript">

     $(document).ready(function(){

          var newId = 1928273643';

          $.ajax({

             type :'get',

             url:'http://news.baibai.com/say/test/testjsonp',

             data : {

                 newId: newId,

             },

             cache:false,

             jsonp:"callback",

            jsonpCallback:"success",

             dataType :'jsonp',

            success:function(data){

                alert(data);

             },

            error:function(data){

                alert('error');

             }       

         });

     });

    </script>

    </head>

    <body>

         <input id=newId'value='546' name=’new'>

         <divid='testdiv'></div>

     </body>

 </html>

jsonp 传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)。

jsonpCallback自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名。

场景2:基于后端Java的跨域

自从HTML5出现之后,极大地方便了日常的开发。其实浏览器并没有拦截请求,而是拦截了服务器端返回的响应。所以如果要支持跨域访问,需要浏览器和后台服务器程序同时支持,如果这两个条件不能同时满足,则还是不能支持跨域访问。

响应头有以下几种:

  • Access-Control-Allow-Origin:允许跨域访问的域,可以是一个域的列表,也可以是通配符”*”;
  • Access-Control-Allow-Methods:允许使用的请求方法,以逗号隔开;
  • Access-Control-Allow-Headers:允许自定义的头部,以逗号隔开,大小写不敏感;
  • Access-Control-Expose-Headers:允许脚本访问的返回头,请求成功后,脚本可以在XMLHttpRequest中访问这些头的信息。
  • Access-Control-Allow-Credentials:是否允许请求带有验证信息,XMLHttpRequest请求的withCredentials标志设置为true时,认证通过,浏览器才将数据给脚本程序。

请求头有以下几种:

  • Origin:表明来源域,要与响应头中的Access-Control-Allow-Origin相匹配才能进行跨域访问;
  • Access-Control-Request-Method:将要进行跨域访问的请求方法,要与响应头中的Access-Control-Allow-Methods相匹配才能进行跨域访问;
  • Access-Control-Request-Headers:自定义的头部,所有用setRequestHeader方法设置的头部都将会以逗号隔开的形式包含在这个头中,要与响应头中的Access-Control-Allow-Headers相匹配才能进行跨域访问。 如果想要能够跨域进行访问,需要设置如下代码,即在返回头中添加一些字段:
代码语言:javascript
复制
@Override

 public void doFilter(ServletRequest request, ServletResponse response) throws IOException,ServletException {

       HttpServletRequest req =(HttpServletRequest) request;

       HttpServletResponse rep =(HttpServletResponse) response;

       // 设置允许请求的域名,即白名单

       String allowDomains = {"http://news.baibai.com/say/three.html "};

       String originHeads = req.getHeader("Origin");

       if(allowOrigins.contains(originHeads)){

             rep.setHeader("Access-Control-Allow-Origin",originHeads);

       }

}

有时候,在跨域访问的时候会存在访问方式是出了post,get类型的,比如options类型,这种会在有的代码中拦截,无法访问,需要在返回头中加如下字段:

代码语言:javascript
复制
response.setHeader("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE");

有时候,访问的请求头首部出现其他类型, 那么Access-Control-Allow-Headers 响应首部预检请求,列出了将会在正式请求的 Access-Control-Expose-Headers 字段中出现的首部信息。如:

代码语言:javascript
复制
response.setHeader("Access-Control-Allow-Headers","x-requested-with,Origin,Accept");

有时候,会出现前端接口对接的时候,后台一直获取不到值。最后发现request里有值,session也有值,但是session的id却不一致。这就是因为跨域引起的,需要在fitter里加上以下代码:

代码语言:javascript
复制
response.setHeader("Access-Control-Allow-Credentials","true");

response.setHeader("XDomainRequestAllowed","1");

注意,当在后端Java代码中加入以上代码时,也需要在前端ajax中加入代码:

代码语言:javascript
复制
var xhr = new XMLHttpRequest();

xhr.withCredentials = true;

再次注意: 服务器端Access-Control-Allow-Credentials = true时,参数Access-Control-Allow-Origin的值不能为 '*'

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是跨域
  • 什么同源策略
  • 跨域如何解决
    • 场景1:基于前端jquery的跨域
      • 场景2:基于后端Java的跨域
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档