目录
一、使用自定义filter实现跨域
1、客户端向服务端发送请求
2、服务端做登录验证了,并生成登路用户对应的token,保存到redis
3、响应(报错)-----跨域问题
4、解决跨域问题--------服务器端添加过滤器,设置请求头
5、重新登录正确响应
6、客户端登redis录后访问页面,需要经过拦截器验证登录状态
7、编写拦截器
二、在任意配置类,返回一个 新的 CorsFIlter Bean
三、使用注解 (局部跨域)
四、手动设置响应头(局部跨域)
前提:前后端分离
一、使用自定义filter实现跨域
1、客户端向服务端发送请求
使用ajax实现登录
<script>
function login(){
var userCode = $("#userCode").val();
var userPassword = $("#userPassword").val();
$.ajax({
url:"http://localhost:9000/login.do",
type:"post",
data: "userCode="+userCode+"&userPassword="+userPassword,
dataType: "text",
success: function (result){
if(result!=null && result!=""){
alert("登录成功")
localStorage.token=result
window.location.href="view/frame.html";
}else {
alert("登录失败")
}
}
})
}
</script>
2、服务端做登录验证了,并生成登路用户对应的token,保存到redis
@RequestMapping ("/login.do")
public String login(String userCode, String userPassword, Model model){
User user = userService.login(userCode,userPassword);
if(user!=null){
//使用UUID生成token
String token = UUID.randomUUID().toString().replace("-","");
//把token保存到redis中,时效1小时
RedisTools.setEx(token,user.getUserName(),1,TimeUnit.HOURS);
System.out.println(token);
return token;
}
return "";
}
3、响应(报错)-----跨域问题
4、解决跨域问题--------服务器端添加过滤器,设置请求头
@Component
@WebFilter("/**")
public class MyCorsFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
//设置字符集编码
HttpServletRequest request = (HttpServletRequest) req;
request.setCharacterEncoding("UTF-8");
HttpServletResponse response = (HttpServletResponse) res;
response.setCharacterEncoding("UTF-8");
//"*":允许任何请求源访问,实际生产环境按公司要求
response.setHeader("Access-Control-Allow-Origin", "*");
//设置请求方式
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
//最大时间
response.setHeader("Access-Control-Max-Age", "3600");
//response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
//添加自定义的请求头信息,"*"任何自定义请求头信息
response.setHeader("Access-Control-Allow-Headers", "*");
System.out.println("*********************************过滤器被使用**************************");
//放行
chain.doFilter(req, res);
}
}
5、重新登录正确响应
6、客户端登redis录后访问页面,需要经过拦截器验证登录状态
客户端登录发送请求时,将token放入请求头中: headers:{"token":localStorage.token},
<script>
function getUserList(){
$.ajax({
url: "http://localhost:9000/user/list.do",
type:"get",
headers:{"token":localStorage.token},
dataType:"text",
success:function (result){
alert(result)
}
})
}
</script>
7、编写拦截器
从请求头中获取token的值,判断是否不为空,且token这个key存在于rdeis中,若存在则放行,反之拦截
public class SysIntercerptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
if(StringUtil.isNullOrEmpty(token) || !RedisTools.hasKey(token)){
System.out.println("登录已过期");
PrintWriter out = response.getWriter();
out.println("alert('登录已过期,请重新登录')");
return false;
}
return true;
}
}
前端
后端
二、在任意配置类,返回一个 新的 CorsFIlter Bean
@Configuration
public class CorsConfig implements WebMvcConfigurer {
//方式1
@Override
public void addCorsMappings(CorsRegistry registry) {
// 设置允许跨域的路由
registry.addMapping("/**")
//是否发送Cookie是否允许证书(cookies)
.allowCredentials(true)
// 设置允许跨域请求的域名------------修改此行//放行哪些原始域
//.allowedOrigins("*")
.allowedOriginPatterns("*")
// 设置允许的方法
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
.allowedHeaders("*")
.exposedHeaders("*");
}
//方式2
// @Override
// public void addCorsMappings(CorsRegistry registry){
// registry.addMapping("/*/**")
// .allowedHeaders("*")
// .allowedMethods("*")
// .maxAge(1800)
// .allowedOrigins("*");
// }
}
When allowCredentials is true, allowedOrigins cannot contain the special value "*" since that cannot be set on the "Access-Control-Allow-Origin" response header. To allow credentials to a set of origins, list them explicitly or consider using "allowedOriginPatterns" instead
当allowCredentials为true时,allowedOrigins不能包含特殊值“*”,因为不能在“Access Control Allow Origin”响应标头上设置该值。要允许一组来源的凭据,请显式列出它们或考虑改“allowedOriginPatterns”
/*将红框中的.allowedOrigins("*")替换为.allowedOriginPatterns("*")即可*/
三、使用注解 (局部跨域)
@CrossOrigin(origins = "*")
四、手动设置响应头(局部跨域)
使用 HttpServletResponse 对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里 Origin的值也可以设置为 “*”,表示全部放行。
@RequestMapping("/index")
public String index(HttpServletResponse response) {
response.addHeader("Access-Allow-Control-Origin","*");
return "index";
}