#2Vite+Vue3+SpringMVC前后端分离 解决跨域问题和session每次请求不一致问题

2024-01-09 12:30:38

目录

一、尝试通过配置请求头和响应头解决(跨域解决了,但session每次请求都不一致)

1、axios配置

2、后端过滤器配置

3、问题复现

4、尝试解决(失败)

5、小结

二、Vite配置Proxy代理解决跨域问题(本地环境)

1、axios配置

2、vite.config

3、后端

4、测试

三、Nginx反向代理解决跨域问题(测试、生产环境)

1、只需在nginx配置如下

2、测试

四、总结


一、尝试通过配置请求头和响应头解决(跨域解决了,但session每次请求都不一致)

1、axios配置

request.interceptors.request.use(config => {
    if (config.method === "get" || config.method === "delete") {
        config.params = {
            ...config.params,
            s_sid: subSessionStore().get(),
        }
    } else {
        config.data = {
            ...config.data,
            s_sid: subSessionStore().get(),
        }
    }
    if (config.file) {
        config.headers['Content-Type'] = 'application/octet-stream;charset=utf-8'
    } else {
        config.headers['Content-Type'] = 'application/json;charset=utf-8'
    }
    config.headers['Accept'] = 'application/json;charset=utf-8';
    config.headers['X-Request-Id'] = getRandomID();
    config.headers['Access-Control-Allow-Origin']='*';
    return config
}, error => {
    console.log('request error: ' + error) // for error debug
    return Promise.reject(error)
})

重点在

Access-Control-Allow-Origin

2、后端过滤器配置

@Order(value = 1)
@WebFilter(filterName = "myCorsFilter", urlPatterns = "/*")
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain)
            throws IOException, ServletException {
        ResponseFacade response =  (ResponseFacade) servletResponse;
//        response.setHeader("Access-Control-Allow-Origin", url);
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,PATCH,DELETE,PUT,OPTIONS,HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers",
                "X-Request-Id,Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Access-Control-Allow-Methods, Access-Control-Allow-Origin");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(servletRequest, servletResponse);
    }

}

3、问题复现

在后端打印sessionId发现:

前端地址为localhost:8080,后端地址为localhost:8282,此时跨域问题解决,session一致。

部署到服务器上后,前端地址为192.xxx.xxx.xxx:8080,后端地址为192.xxx.xxx.xxx:8282,此时跨域问题解决,session一致。

部署到服务器上后,前端地址为本机localhost:8080,后端地址为192.xxx.xxx.xxx:8282,此时跨域问题解决,session出现不一致。

4、尝试解决(失败)

axios配置:

const request = axios.create({
    baseURL:baseUrl
    timeout: 10000,
    withCredentials: true
})

查了一些资料说需需要增加

withCredentials

来携带Cookie(虽然此时已经携带Cookie,不知道这些人从哪里抄来的),前端提示此时不可以再使用

['Access-Control-Allow-Origin']='*';

于是同时修改前端axios配置和后端过滤器配置:

config.headers['Access-Control-Allow-Origin'] = apiUrl;
response.setHeader("Access-Control-Allow-Origin", url);

本地调试:没有问题

部署到服务器调试:跨域请求直接过不去

5、小结

实际上域名、端口、协议只要任一不同,都是跨域,但是实际测试发现相同域名下访问sessionId可以保持不变,况且cookie已经携带。上面的解决办法行不通,但暂时没有搞懂为什么。

二、Vite配置Proxy代理解决跨域问题(本地环境)

1、axios配置

const request = axios.create({
    baseURL: '/back',
    timeout: 10000,
})

request.interceptors.request.use(config => {
    //...
    config.headers['Access-Control-Allow-Origin']='*';
    //...
})

此处baseURL与下方配置对应,不再使用前面直接指定后端地址的方式。

2、vite.config

    server: {
        proxy: {
            '/back': {
                target: 'http://localhost:8080/back/',
                changeOrigin: true,
                rewrite: (path) => path.replace(/^\/back/, '')
            }
        }
    }

3、后端

把前面配置的cors过滤器删掉。

4、测试

跨域:没有问题

session:id保持一致

三、Nginx反向代理解决跨域问题(测试、生产环境)

1、只需在nginx配置如下

location ^~/back/ {
     proxy_pass http://xxx.xxx.xxx.xxx:8080/back/;
 }

2、测试

跨域:没有问题

session:id保持一致

四、总结

跨域常用解决方案包括:

jsonp:利用script标签可跨域的特点,在跨域脚本中可以直接回调当前脚本的函数

cors:服务器设置http响应头中的Access-Control-Allow-Origin值,解除跨域限制

node:中间代理

nginx:反向代理

其中vite配置的属于中间代理,适用于本地开发环境;

nginx配置反向代理,适用于生产环境。

如果对你有帮助,点赞、收藏、关注是我更新的动力哟!

文章来源:https://blog.csdn.net/weixin_42718399/article/details/135388463
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。