美文网首页
跨域分析

跨域分析

作者: 梧桐树简友 | 来源:发表于2020-07-09 23:25 被阅读0次

    浏览器为什么会产生跨域访问安全问题

    浏览器的限制

    浏览器为了安全考虑会限制不同域下的请求资源访问. 跨域的简单请求(这里还有非简单请求,是先做个options请求预校验,通过了才会真正请求)还是可以正常到达后台,后台也可以正常执行返回,但是浏览器就是给报,跨域安全错误.

    跨域请求

    如果请求里面,协议 域名 端口 任何一个不一样,都会被认为是跨域的请求.

    XHR (XMLHttpRequest) 请求

    主要就是因为发起的请求是这种类型的,也就是说,即使你协议,域名 端口都不一样,只要请求类型不是这种xhr的,就不会产生跨域问题.比如 直接用img,script标签或者其他形式请求同样的接口地址, 就不会有跨域问题.


    针对三种原因的解决思路

    浏览器限制

    可以通过比较麻烦的设置,让浏览器不要限制跨域安全请求. 但是这种的比较麻烦而且不是正道.
    启动浏览器的时候,带上参数,比如不要去双击chrome的图标启动.而且用命令行窗口如下启动
    chrome --disable-web-security --user-data-dir=d:\tmp

    XHR请求

    可以使用jsonp的形式,将原先是xhr类型的请求修改为非xhr的请求来处理,jsonp是一种动态生产script脚本的形式来请求对应接口.所以不存在跨域的问题.但是也要修改后台代码,后台不能直接返回普通的纯数据格式文本,要返回可以被解析为script的内容. 浏览器F12观察,可以知道jsonp请求的类型是 script,并且自动给请求加上了callback参数. 后台就得想办法判断如果参数里有callback的话,就给返回的数据,包装一层,让他变成js代码.
    类似这样:请求指定callback=tmpfunction , 那么后台返回给前台的文本就要是 "tmpfunction(原先的返回纯数据内容文本)" 并且如果使用jquery的话,会临时生成一个脚本区域,来容纳这个方法.并且使用完后,立马被清理掉.
    Jsonp 是利用script请求的,所以只支持get的方法了.弊端比较大

    跨域

    可以让接口方修改后台代码,通过配置允许跨域请求的源域名列表,来过滤一些白名单域的请求.但是这种的比较局限接口必须是我们可控制的. 还可以修改调用方的代码,或者http服务器配置信息,使用代理的方法,让xhr的请求,请求自己本域下的某个地址,然后转发到请求接口.然后将返回的结果,转手倒给调用方.
    比如参考
    https://www.cnblogs.com/ddlove/p/9945988.html
    https://blog.csdn.net/supramolecular/article/details/84234129


    虽然但是

    虽然这么多,但是大部分场景就是把下面的代码拿走,加到一个filter里,基本可以解决掉了就。
    public class CrosFilter implements Filter

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
             throws IOException, ServletException {
          HttpServletResponse res = (HttpServletResponse) response;
         HttpServletRequest req = (HttpServletRequest) request;
         String origin = req.getHeader("Origin");
         if (!org.springframework.util.StringUtils.isEmpty(origin)) {
             //带cookie的时候,origin必须是全匹配,不能使用*
             res.addHeader("Access-Control-Allow-Origin", origin);           
         }
         res.addHeader("Access-Control-Allow-Methods", "*");
         String headers = req.getHeader("Access-Control-Request-Headers");
         // 支持所有自定义头
         if (!org.springframework.util.StringUtils.isEmpty(headers)) {
             res.addHeader("Access-Control-Allow-Headers", headers);         
         }
         res.addHeader("Access-Control-Max-Age", "3600");
         // enable cookie
         res.addHeader("Access-Control-Allow-Credentials", "true");
         chain.doFilter(request, response);
     }
    

    相关文章

      网友评论

          本文标题:跨域分析

          本文链接:https://www.haomeiwen.com/subject/fftycktx.html