SouthLight's Blog


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

解决跨域问题

发表于 2019-01-31 | 分类于 问题

什么是跨域问题?

跨域,指浏览器从一个域名的网页去请求另一个域名的资源(比如请求API)时,由于域名或者端口不同,导致资源不能访问,这就是跨域问题。
比如:网页www.lnw.com/index.html 请求接口—-> www.api.com/get,此时由于域名的不同就会有跨域问题的出现

或者 localhost:8081/index.html 请求接口—–> localhost:8082/get ,此时由于端口的不同也会有跨域问题的出现

解决办法

Spring项目的解决办法:

一、使用@CrossOrigin

在controller加上该注解,即可解决

1
2
3
4
5
6
@CrossOrigin(origins = {"http://localhost"})
@Controller
// 加上注解
public class StudentController{
...
}

允许80端口跨域
但这样的每个Controller都要加上该注解,有点麻烦

二、实现WebMvcConfigurer的addCrosMappings方法

实现该方法可以让所有的Controller能够允许跨域

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/**
* SpringMVC 配置类
* @author SouthLight
*/
@Configuration
@EnableWebMvc
public class MVCApplicationConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("http://localhost")
.allowedOrigins("*")
.allowCredentials(true)
.allowedMethods("GET", "POST", "DELETE", "PUT")
.maxAge(3600);


}
}

三、配置Filter过滤器

上诉两种方法好像不能解决Cookie传递的问题,因为Cookie的跨域传递需要前后两端都要规定头部的协议:Access-Control-
设置过滤器不仅可以对请求进行拦截,还可以对请求的request和response进行修改
自己实现Filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.helper.config;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* Filter过滤器
* 解决跨域问题
* @author SouthLight-Lin
*/
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("---初始化----");
}

@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpServletRequest request = (HttpServletRequest)servletRequest;
System.out.println("MyFilter拦截:"+request.getServletPath());
String origin = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
String method = request.getMethod();
if(method.equalsIgnoreCase("OPTIONS")){
servletResponse.getOutputStream().write("Success".getBytes("utf-8"));
}else{
filterChain.doFilter(servletRequest, servletResponse);
}
}
@Override
public void destroy() {

}

}

前端的请求需要设置头部Access-Control-,后端的response也需要设置相同的头部,不然的话也还是不能访问

添加Filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* SpringMVC 配置类
* @author SouthLight
*/
@Configuration
@EnableWebMvc
public class MVCApplicationConfig implements WebMvcConfigurer {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
// 将Filter注册
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new MyFilter());
registration.addUrlPatterns("/*");
registration.addInitParameter("paramName", "paramValue");
registration.setName("myFilter");
registration.setOrder(1);
return registration;
}



}

这样就可以解决跨域以及Cookie的传递了

使用Nginx解决跨域问题

因为前端项目一般都是部署在Nginx的服务器上,我们可以让Nginx代理我们请求资源的接口,比如我有一个前端项目,部署端口80的根目录“/”,后端接口8080部署Nginx代理路径“/api”
nginx.conf

location / {
    root   html/homework-helper-frontend/html;
    index  index.html index.htm;
}

# 服务器访问路径
location /api{
    # 将/api代理到下面的地址
    proxy_pass http://localhost:8080/api;
}

如此一来,我们输入localhost/index.html就可以访问网页
输入localhost/api/get,Nginx就会代理,转成请求localhost:8080/api这个地址,完美的解决了跨域的问题,而且cookie也可以正常传递

美滋滋·~~~~

1…35363738

SouthLight Lin

38 日志
16 分类
19 标签
© 2020 SouthLight Lin
由 Hexo 强力驱动
|
主题 — NexT.Muse v5.1.4