• 跨域相关问题


    允许跨域的方式

      1、JSONP,只能发出get请求

        使用<script src="">来完成一个跨域请求:

            当点击"跨域获取数据"的按钮时,添加一个<script>标签,用于发起跨域请求;注意看请求地址后面带了一个callback=showData的参数;

            showData即是回调函数名称,传到后台,用于包裹数据。数据返回到前端后,就是showData(result)的形式,因为是script脚本,所以自动调用showData函数,而result就是showData的参数。

            至此,我们算是跨域把数据请求回来了,但是比较麻烦,需要自己写脚本发起请求,然后写个回调函数处理数据,不是很方便。

        

     1 //回调函数
     2          function showData (result) {
     3              var data = JSON.stringify(result); //json对象转成字符串
     4             $("#text").val(data);
     5          }
     6  
     7          $(document).ready(function () {
     8  
     9              $("#btn").click(function () {
    10                 //向头部输入一个脚本,该脚本发起一个跨域请求
    11                  $("head").append("<script src='http://localhost:9090/student?callback=showData'></script>");
    12              });
    13  
    14          });

          服务端:

     

     1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
     2      response.setCharacterEncoding("UTF-8");
     3      response.setContentType("text/html;charset=UTF-8");
     4  
     5      //数据
     6      List<Student> studentList = getStudentList();
     7  
     8  
     9      JSONArray jsonArray = JSONArray.fromObject(studentList);
    10      String result = jsonArray.toString();
    11  
    12      //前端传过来的回调函数名称
    13      String callback = request.getParameter("callback");
    14      //用回调函数名称包裹返回数据,这样,返回数据就作为回调函数的参数传回去了
    15      result = callback + "(" + result + ")";
    16  
    17      response.getWriter().write(result);
    18  }

        jquery的jsonp方式跨域请求:

             服务端代码不变,js代码如下:最简单的方式,只需配置一个dataType:'jsonp',就可以发起一个跨域请求。jsonp指定服务器返回的数据类型为jsonp格式,可以看发起的请求路径,自动带了一个callback=xxx,xxx是jquery随机生成的一个回调函数名称。

             这里的success就跟上面的showData一样,如果有success函数则默认success()作为回调函数。

     1 $(document).ready(function () {
     2  
     3              $("#btn").click(function () {
     4  
     5                  $.ajax({
     6                      url: "http://localhost:9090/student",
     7                      type: "GET",
     8                      dataType: "jsonp", //指定服务器返回的数据类型
     9                      success: function (data) {
    10                          var result = JSON.stringify(data); //json对象转成字符串
    11                          $("#text").val(result);
    12                      }
    13                  });
    14  
    15              });
    16  
    17          });

            指定回调函数至于在上面加上     jsonpCallback: "showData", //指定回调函数名称,但success()方法在调用过指定回调函数后仍会调用。

      2、CORS

          1、在允许跨域访问的方法内设置response,只允许此方法跨域访问

     

    1         response.addHeader("Access-Control-Allow-Origin", "*");
    2         response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
    3         response.addHeader("Access-Control-Allow-Headers", "Content-Type");
    4         response.addHeader("Access-Control-Max-Age", "1800");//30 min

           2、在拦截器中配置,配置在项目的web.xml中时,整个项目接口均允许跨域

    <filter>
        <filter-name>cros</filter-name>
        <filter-class>cn.ifengkou.test.filter.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>cros</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    @Component
    public class CORSFilter extends OncePerRequestFilter {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.addHeader("Access-Control-Max-Age", "1800");//30 min
            filterChain.doFilter(request, response);
        }
    }

          3、SpringMVC提供@CrossOrigin注解允许跨域,加载类上表示整个controller都可跨域,用在方法上表示此方法允许跨域

          4、tomcat配置允许跨域

          5、nginx配置允许跨域

    #
    # Wide-open CORS config for nginx
    #
    location / {
         if ($request_method = 'OPTIONS') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            #
            # Custom headers and headers various browsers *should* be OK with but aren't
            #
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
            #
            # Tell client that this pre-flight info is valid for 20 days
            #
            add_header 'Access-Control-Max-Age' 1728000;
            add_header 'Content-Type' 'text/plain charset=UTF-8';
            add_header 'Content-Length' 0;
            return 204;
         }
         if ($request_method = 'POST') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
         }
         if ($request_method = 'GET') {
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
         }
    }

    注意:重定向的跨域访问中 Access-Control-Allow-Origin的值不能设置为‘*’,必须设置为具体的源

    shiro中对跨域的支持

      对简单请求支持,非简单请求时需重写 FormAuthenticationFilter中的isAccessAllowed方法

    protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
            return request instanceof HttpServletRequest && ((HttpServletRequest)request).getMethod().toUpperCase().equals("OPTIONS") ? true : super.isAccessAllowed(request, response, mappedValue);
        }

     

    跨域请求时,浏览器会过滤相关响应头中自定义的key,想要不过滤,在服务端响应头中写入不需过滤的key

        response.setHeader("Access-Control-Expose-Headers", "所要展示的key")

  • 相关阅读:
    10 查看创建表的语句:show create table emp;
    9 常用命令?
    8 如何查看表中的数据?
    7 查看表结构
    构建之法阅读笔记3
    每日汇报
    每周总结
    每日汇报
    每周总结
    每日总结
  • 原文地址:https://www.cnblogs.com/fg-fd/p/9896765.html
Copyright © 2020-2023  润新知