问?:为什么明明没有返回model,data的数据还可以带到前端?
答案:关键在于参数类型是 Map<String, Object>,Spring 会自动注入 Model 对象。而参数名(如 data 或 model)只是在方法内部引用这个 Model 对象的标识符,不影响功能实现。
问?:为何通过 var subscribeUrl = [[${subscribe}]]; var source = new EventSource(subscribeUrl); 就传递了 id 参数。?
答案:假设 ip 是 192.168.1.100,port 是 8080,生成的 id 是 abc123,那么存入 data 的 "subscribe" 对应的值就是 http://192.168.1.100:8080/subscribe?id=abc123。
[[${subscribe}]] 是 Thymeleaf 的内联表达式,在服务器端渲染模板时,Thymeleaf 会从 Model 中获取键为 "subscribe" 的值,也就是之前后端存入 data 里的完整 URL,然后将这个值替换到 JavaScript 代码中。
EventSource 会向 subscribeUrl 发起请求,由于 subscribeUrl 包含 id 参数,所以请求时就把 id 参数传递给了服务器。最终发送的请求 URL 是 http://192.168.1.100:8080/subscribe?id=abc123,服务器可以从这个请求的查询参数里获取 id 的值。
综上所述,通过后端生成带 id 参数的 URL,Thymeleaf 模板渲染传递 URL,前端使用 EventSource 访问该 URL,就实现了 id 参数的传递。
微信登入最后一问:什么情况会未登入??不是都login了吗?
答案:虽然代码里有登录逻辑,但仍存在多种情况会导致用户被判定为未登录,下面详细分析:
- 前端未正确设置 cookie
在前端代码里,使用 document.cookie 来设置 cookie,若出现异常,cookie 可能未正确设置。
javascript
Apply
if (text.startsWith('login#')) {
// 登录格式为 login#cookie
var cookie = text.substring(6);
document.cookie = cookie;
window.location.href = [[${redirect}]];
source.close();
}
cookie 格式错误:后端返回的 cookie 格式若不符合规范,浏览器可能会忽略该 cookie。例如,缺少必要的属性(如 path、expires 等)。
浏览器安全策略限制:部分浏览器的安全策略可能会阻止 cookie 的设置,比如在 http 环境下尝试设置 Secure 属性的 cookie,或者在跨域请求时设置 cookie 但未满足相应条件。
2. cookie 未正确传递到首页
即使 cookie 成功设置,在跳转首页时也可能因各种原因未传递到服务器。
cookie 作用域问题:cookie 的 path 和 domain 属性会影响其作用范围。若 path 设置不正确,首页请求可能不会携带该 cookie。例如,cookie 的 path 设置为 /api,而首页路径为 /home,则请求 /home 时不会携带该 cookie。
cookie 过期:若 cookie 设置了过期时间,且在跳转首页前已过期,那么请求首页时该 cookie 不会被发送到服务器。
3. 后端缓存问题
在 accept 接口中,使用缓存来管理 SseEmitter 实例。
java
Apply
@ResponseBody
@GetMapping(path = "accept")
public String accept(String id, String token) throws IOException {
SseEmitter sseEmitter = cache.get(id);
if (sseEmitter != null) {
// 发送登录成功事件,并携带上用户的token,我们这里用cookie来保存token
sseEmitter.send("login#qrlogin=" + token);
sseEmitter.complete();
cache.remove(id);
}
return "登录成功: " + token;
}
缓存失效:若缓存机制存在问题,如缓存过期时间设置过短,可能导致 SseEmitter 实例提前从缓存中移除,使得 accept 接口无法找到对应的实例,从而无法发送登录成功消息。
缓存数据不一致:在高并发场景下,可能会出现缓存数据不一致的情况,导致 accept 接口处理异常。
4. 代码逻辑异常
accept 接口未正确执行:若 accept 接口在执行过程中抛出异常,如 IOException,可能会导致 sseEmitter.send 方法未被调用,前端也就无法接收到登录成功消息。
首页接口异常:首页接口在获取 cookie 或处理 cookie 时可能出现异常,如 request.getCookies() 返回 null 且未正确处理,或者 Stream.of(cookies) 操作时 cookies 为 null 导致空指针异常。
5. 网络问题
请求丢失:在跳转首页的过程中,若网络不稳定,可能会导致请求丢失或中断,使得 cookie 未正确传递到服务器。
服务器响应异常:服务器在处理首页请求时可能出现异常,无法正常读取 cookie 信息。
浙公网安备 33010602011771号