请教一下关于跨域方面的问题,主要是后台、springboot 方面的问题。

2018-12-03 12:49:16 +08:00
 ukipoi

SpringSession,右边这个"spring-session-data-redis",是怎么实现共享的?存放在 redis 里就是共享吗?
但是我在使用过程中获取 session 还是 request.getSession(),那我要怎么根据 session.getId()来获得我想要的 session 呢?
我觉得上面的问题只要是我不理解跨域是怎么回事。我现在遇到了这么一个问题。有一个后台访问的端口是 8081,而前台的页面是在 80 端口上的,所以前台所有的 ajax 请求,我在后台 request.getSession().getId()都是不一样的,这种情况就是跨域问题吧?
一开始的时候找到一些解决跨域的方法,但是好像没有什么效果,而且自己也没理解是什么原理。自己猜测跨域的原因是服务器禁止了一些不符合要求的请求访问,这些解决跨域的方法是允许这些请求的访问。请问这个理解对么?

@Configuration
public class CorsConfig {
    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedOrigin("*"); 
        corsConfiguration.addAllowedHeader("*"); 
        corsConfiguration.addAllowedMethod("*");
        return corsConfiguration;
    }

    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CorsFilter(source);
    }
}
@Configuration
public class CrossInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        if (request.getHeader(HttpHeaders.ORIGIN) != null) {
            String origin = request.getHeader("Origin");
            response.addHeader("Access-Control-Allow-Origin", origin);
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT,PATCH, HEAD");
            response.addHeader("Access-Control-Allow-Headers", "Content-Type");
            response.addHeader("Access-Control-Max-Age", "3600");
        }
        return true;
    }
}

不好意思,我有点找不到学习的方向了,希望各位大大给我指点一下,不要嫌弃我伸手呀。

2532 次点击
所在节点    Java
11 条回复
ayase252
2018-12-03 12:58:49 +08:00
跨域是因为前端浏览器为了安全,限制了对非同源资源的请求。用 CORS 可以让前端发起跨域请求,但是需要服务器的配合。可以看一下这篇[文档]( https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS)
qinxi
2018-12-03 13:24:22 +08:00
跨域跟 session 有什么关系..
跨域是浏览器实现的限制.
如果只是处理跨域
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");//调用方域名
config.addAllowedHeader("*");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("OPTIONS");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}

session 这个东西你就把他当作是一个 map. 以前是在单机上.spring-session-redis 只是把这个东西变成共享的了.
集群更方便.

session 和跨域没啥关系, 默认情况下:只要你带上正确的 cookie, 请求就可以被正常的处理, 之后浏览器才会针对 ResponseHeader 做跨域检测.

由于上面说的方式会存在风险: 就算不让跨域, 可是服务端已经处理了.

options 请求.用来预检测是否允许接下来的实际请求. 这个请求通常没有实际作用.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS
chanchan
2018-12-03 13:30:42 +08:00
复制一段阿里云文档的内容给你看看:
跨域访问,或者说 JavaScript 的跨域访问问题,是浏览器出于安全考虑而设置的一个限制,即同源策略。当来自于 A 网站的页面中的 JavaScript 代码希望访问 B 网站的时候,浏览器会拒绝该访问,因为 A、B 两个网站是属于不同的域。

在实际应用中,经常会有跨域访问的需求,比如用户的网站 www.a.com ,后端使用了 OSS。在网页中提供了使用

JavaScript 实现的上传功能,但是在该页面中,只能向 www.a.com 发送请求,向其他网站发送的请求都会被浏览器拒绝。这样就导致用户上传的数据必须从 www.a.com 中转。如果设置了跨域访问的话,用户就可以直接上传到 OSS 而无需从 www.a.com 中转。
-----------------------------------------------------------
我感觉你已经解决了跨域问题,你接下来要解决的是让 sessionId 保持不变
ukipoi
2018-12-03 14:10:59 +08:00
@chanchan
但是,如果网页和后台放在一起,sessionId 就可以保持不变。
分开的话,sessionId 就会一直变化了。造成这个的原因不是因为跨域吗?
sutra
2018-12-03 14:19:49 +08:00
sessionId 变化是因为你是采用的 cookie 跟踪 Session 吧。
V2XEX
2018-12-03 14:23:13 +08:00
@ukipoi 你确定 session 变化是由于跨域造成的?请你说清楚你的使用场景
wly19960911
2018-12-03 14:26:59 +08:00
首先去看看 session 的原理,session id 和 session 的关系,还有 sessionid 存放在浏览器哪里( cookies )。

跨域问题,使用插件可以解决 https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi,这个成本相对比较低,真正解决需要反向代理,如果可以的话解释下,为什么前端和后端端口不一致,前端 npm start 启动了调试服务器吗,这个的话,npm 有个 proxyTable 去处理反代问题
chanchan
2018-12-03 14:35:14 +08:00
@ukipoi 也是因为跨域。那我说准确点,你已经解决跨域禁止访问的问题了,还需解决跨域 sessionId 一直变的问题
ukipoi
2018-12-03 14:40:47 +08:00
@V2XEX
springboot 的项目,直接使用了 springsession 和 redis。
然后前台页面是放在一个端口为 80 的容器,后台程序是放在一个端口 8081 的容器。
在 80 端口的页面访问 8081 端口的后台。后台通过 request.getSession 获取 httpSession。
不过看样子是我没设置 Access-Control-Allow-Credentials: true 和前台没有在 Ajax 请求里加上[ xhrFields: { withCredentials: true},crossDomain: true, ]的问题。
haoz1w0w
2018-12-03 14:51:20 +08:00
@ukipoi 如果我没记错的话 设置了 Access-Control-Allow-Credentials: true 的话 config.addAllowedOrigin("*");//调用方域名 就不能用*了 要去动态获取一下 response.setHeader("Access-Control-Allow-Origin", ((HttpServletRequest) request).getHeader("Origin"));
YzSama
2018-12-05 20:02:18 +08:00
跨域和 session 共享不是一个问题吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/513790

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX