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中添加额外的代码了