小知识,大挑战!本文正在参与“程序员必备小知识”创作活动
前言:昨天在项目部署的时候遇见了跨域问题,今天来补上自己当时的解决方式和好奇。
身边的跨域:自己工作的这些时间里经常听见身边的人提起到跨域的问题,在我的心中第一个想到的是vue的反向代理来解决跨域问题,服务端设置权限、nginx的请求头控制等。
针对vue的跨域我们可以用下面的方式来解决(proxyTable):
这里vue脚手架生成的标准项目为准。一般在项目config目录下面有个index文件。
const path = require('path')
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/sys':{
target:'http://localhost:9002',
changeOrgin:true,
pathRewrite:{
'^/sys':'/sys'
}
}
},
host: 'localhost',
port: 8888,
autoOpenBrowser: false,
errorOverlay: true,
notifyOnErrors: false,
poll: false,
useEslint: true,
showEslintErrorsInOverlay: false,
devtool: '#cheap-source-map',
cacheBusting: true,
cssSourceMap: false,
},
针对服务器如JAVA我们可以使用之前说到的来处理如下:
方式一:filter)
public class SimpleCORSFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
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");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
在web.xml中写入
<filter>
<filter-name>cors</filter-name>
<filter-class>com.ssm.web.filter.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</filter>
其中你也可以为单个action提供跨域HttpServletResponse解决如下:
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");
方式二:
在SpringBoot中的解决方式
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 实现跨域请求
* @author
*
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
final CorsConfiguration corsConfiguration = new CorsConfiguration();
/*是否允许请求带有验证信息*/
corsConfiguration.setAllowCredentials(true);
/*允许访问的客户端域名*/
corsConfiguration.addAllowedOrigin("*");
/*允许服务端访问的客户端请求头*/
corsConfiguration.addAllowedHeader("*");
/*允许访问的方法名,GET POST等*/
corsConfiguration.addAllowedMethod("*");
urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
return new CorsFilter(urlBasedCorsConfigurationSource);
}
}
在nginx中解决跨域:
方式一:反向代理
server {
listen 80;
server_name localhost;
location /Api {
proxy_pass http://localhost:8080/Api;
index index.html index.htm;
}
}
方式二:控制请求头
location / {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
if ($request_method = 'OPTIONS') {
return 222;
}
}
补充:昨天遇见的问题是我没想到的,当时排查了5分钟原来是TOMCAT1.9的跨域问题,毕竟是自己没有听说过这个说法,当时也是自己的猜测,没想到在网上找了一些资料后,还真有这种解决方式,当时的自己抱着试一试的态度和一定理论推理的去实践,原来还真是这个问题。
TOMCAT1.9解决方式如下在conf文件的web.xml的预计400行左右插入如下代码:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</filter>