• 跨域


    一. 什么是跨域:

    域名地址的组成:

    http:// www . google : 8080 / script/jquery.js

    1. http:// (协议号)

    2. www  (子域名)

    3. google (主域名)

    4. 8080 (端口号)

    script/jquery.js (请求的地址)

    * 当协议子域名主域名端口号中任意一各不相同时,都算不同的“”。

    不同的域之间相互请求资源,就叫“跨域”。

    比如:http://www.abc.com/index.html 请求 http://www.def.com/sever.php

     同源策略

    同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。

    二. 处理跨域的方法

    1. JSONP

    JSONP 跨域请求, 可以参考我这篇博客   Jsonp 跨域 处理

    2. 响应头中设置  Access-Control-Allow-Origin

    //如果是普通的前端跨域请求的话, 就直接在后端返回参数时设置响应头就可以了 
    response.setHeader("Access-Control-Allow-Origin", "*");

    3. CORS 跨域(OPTIONS)

    浏览器会在发送真正请求之前,先发送一个方法为OPTIONS的预检请求 Preflighted requests 这个请求是用来验证本次请求是否安全的,而且并不是所有请求都会发送,需要符合以下条件:

    • 请求方法不是GET/HEAD/POST
    • POST请求的Content-Type并非application/x-www-form-urlencoded, multipart/form-data, 或text/plain
    • 请求设置了自定义的header字段

    对于管理端的接口,我有对接口进行权限校验,每次请求需要在header中携带自定义的字段(token),所以浏览器会多发送一个OPTIONS请求。

    那为什么OPTIONS请求报错了。。。

    经过debug发现,OPTIONS请求只会携带自定义的字段,并不会将相应的值带入进去,而后台校验token字段时 token为NULL,所以验证不通过,抛出了一个异常。

    解决

    先在项目中加个过滤器 Filter. 
    import org.springframework.stereotype.Component;
    
    import java.io.IOException;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @Component
    public class OriginFilter implements Filter {
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            HttpServletRequest httpRequest = (HttpServletRequest) request;
            httpResponse.setHeader("Access-Control-Allow-Origin", httpRequest.getHeader("Origin"));
            httpResponse.setHeader("Access-Control-Allow-Methods", httpRequest.getMethod());
            httpResponse.setHeader("Access-Control-Max-Age", "3600");
            httpResponse.setHeader("Access-Control-Allow-Headers", httpRequest.getHeader("Access-Control-Request-Headers"));
            chain.doFilter(request, response);
        }
    
        @Override
        public void destroy() {
            
        }
    }
    然后在你项目的拦截器中 放行就行
     if ("OPTIONS".equals(request.getMethod())) {
                response.setStatus(HttpServletResponse.SC_OK);
                return true;
            }
    

      实际代码根据实际项目, 实际需求来, 但是原理是一样的.  可以根据原理来写相对应的代码

      CORS 详解可以 去查看,参考这篇博客 跨域资源共享 CORS 详解

    4. 代理

      比如在北京(www.beijing.com/sever.php)和上海(www.shanghai.com/sever.php)各有一个服务器,北京的后端(www.beijing.com/sever.php)直接访问上海的服务,然后把获取的响应值返回给前端。也就是北京的服务在后台做了一个代理,前端只需要访问北京的服务器也就相当与访问了上海的服务器

  • 相关阅读:
    leetcode面试准备:Kth Largest Element in an Array
    leetcode面试准备:Minimum Size Subarray Sum
    leetcode面试准备:Valid Anagram
    leetcode面试准备:Divide Two Integers
    leetcode面试准备:Container With Most Water
    面试:归并排序和分治法
    leetcode面试准备:Lowest Common Ancestor of a Binary Search Tree & Binary Tree
    Leetcode解题思想总结篇:双指针
    leetcode面试准备: CountPrimes
    RF中BDD编写
  • 原文地址:https://www.cnblogs.com/jingjiren/p/13131191.html
Copyright © 2020-2023  润新知