zoukankan      html  css  js  c++  java
  • 前后端分离之解决跨域问题

    1. 建立前端项目

    在HbuilderX里面新建一个名为front的项目

    index.html里面的内容为:

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="utf-8">
      <title>前端页面</title>
      <script src="jquery-3.5.1.min.js"></script>
    </head>
    
    <body>
      <p>使用Ajax从后端获取到的信息为:</p>
      <p id="msg" style="color: red;"></p>
      
      <script>
        $.ajax({
          url: "http://localhost:8080/back/MessageServlet",
          method: "GET",
          success: function(data) {
            $("#msg").text(data);
          }
        })
      </script>
    </body>
    

    可以看到,前端服务器的主机名和端口号为:127.0.0.1:8848

    HbuilderX的内置服务器是一个通用的Node的webserver

    2. 建立后端项目

    在Eclipse里面新建一个名为back的项目

    MessageServlet.java里面的内容为:

    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    
    @WebServlet("/MessageServlet")
    public class MessageServlet extends HttpServlet {
        
        private static final long serialVersionUID = 1L;
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 设置编码
            response.setCharacterEncoding("GBK");
            // 返回的消息
            PrintWriter out = response.getWriter();
            out.print("返回的消息");
        }
        
    }
    

    可以看到,后端Tomcat服务器的主机名和端口号为:127.0.0.1:8080

    我们可以直接通过输入相应路径的方式来查看Servlet返回的消息

    3. 在Servlet中进行配置

    此时,前后端项目都已经建立完成,前端页面通过Ajax方式向后台请求数据,但是前端页面并没有获取到返回的消息,同时控制台显示如下信息:

    CORS:Cross Origin Resource Sharing,跨域资源共享。

    出于安全的考虑,浏览器不允许Ajax访问当前(如果两个页面的协议、主机名和端口号都相同,则两个页面具有相同的源)之外的资源,即同源策略。

    那么这时我们就需要规避同源策略来实现跨域请求。

    解决跨域的方式有很多,这里使用一种在后端设置的方式,在MessageServlet中添加如下代码:

    package servlet;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    
    @WebServlet("/MessageServlet")
    public class MessageServlet extends HttpServlet {
        
        private static final long serialVersionUID = 1L;
        
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // 设置编码
            response.setCharacterEncoding("UTF-8");
            
            // 允许跨域的主机地址
            response.setHeader("Access-Control-Allow-Origin", "*");
            // 允许跨域的请求头
            response.setHeader("Access-Control-Allow-Headers", "*");
            // 允许跨域的请求方法
            response.setHeader("Access-Control-Allow-Methods", "*");
            // 是否允许携带cookie
            response.setHeader("Access-Control-Allow-Credentials", "true");
            // 重新预检验跨域的缓存时间
            response.setHeader("Access-Control-Max-Age", "3600");
            
            // 返回的消息
            PrintWriter out = response.getWriter();
            out.print("返回的消息");
        }
        
    }
    

    刷新前端页面,可以看到消息正常显示:

    4. 使用Filter

    将Servlet中的代码放置在Filter中

    新建一个名为CORSFilter的Filter

    package servlet;
    
    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.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    @WebFilter(filterName = "/CORSFilter", urlPatterns = {"/*"})
    public class CORSFilter implements Filter {
    
        public CORSFilter() {}
    
        public void destroy() {}
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            
            HttpServletRequest httpServletRequest = (HttpServletRequest) request;
            HttpServletResponse httpServletResponse = (HttpServletResponse) response;
            
            httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Headers", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Methods", "*");
            httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
            httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
            
            chain.doFilter(httpServletRequest, httpServletResponse);
            
        }
    
        public void init(FilterConfig fConfig) throws ServletException {}
    
    }
    

    这样就不需要再在每个Servlet中添加额外的代码了

  • 相关阅读:
    openwrt 相关文章
    负载均衡相关文章
    Today's Progress
    Rodrigues formula is beautiful, but uneven to sine and cosine. (zz Berkeley's Page)
    Camera Calibration in detail
    Fundamental Matrix in Epipolar
    Camera Calibration's fx and fy do Cares in SLAM
    FilterEngine::apply
    FilterEngine 类解析——OpenCV图像滤波核心引擎(zz)
    gaussBlur
  • 原文地址:https://www.cnblogs.com/qintang/p/13821654.html
Copyright © 2011-2022 走看看