跨域问题解决与学习

365 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

前言:昨天在项目部署的时候遇见了跨域问题,今天来补上自己当时的解决方式和好奇。

身边的跨域:自己工作的这些时间里经常听见身边的人提起到跨域的问题,在我的心中第一个想到的是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>

以上就是我分享的跨域问题以及解决方式。若还有其他方法欢迎在评论区留言!