赞
踩
今天碰到一个很棘手的问题,前端请求后端不带cookie,
请求时header里面就是没有cookie,可能还少了点其他东西
很头疼,尝试了很多办法,还是不行,比如下面几种:
1:我是用的axios请求的,很多人只加下面这一行代码就搞定了,但是,我没有
- // 允许携带cookie
- axios.defaults.withCredentials=true
2:然后,有人加withCredentials之外,还加了其他的一些东西 才成功了,如下:
- // 设置
- axio.withCredentials = true;
- axio.defaults.withCredentials = true;
-
- // 或者这样设置
- axio.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
- axio.defaults.crossDomain = true;
- axio.defaults.withCredentials = true; //设置cross跨域 并设置访问权限 允许跨域携带cookie信息
- axio.defaults.headers.common['Authorization'] = ''; // 设置请求头为 Authorization
-
- return axio.post(PATH.FINANCE_APL_LIST,data, {withCredentials:true
- }).then(res=>{
- console.log("OKOKOK2-------------------",res)
- return res.data.retObj
- })
但很可惜,我还是失败了
3:有的人说这样加,做一个全局的设置:
- import axios from "axios";
- // Create an instance using the config defaults provided by the library
- // At this point the timeout config value is `0` as is the default for the library
- const axio = axios.create({
- headers: {
- "Content-Type": "application/json;charset=UTF-8"
- }
- });
-
- // Override timeout default for the library
- // Now all requests using this instance will wait 2.5 seconds before timing out
- axio.defaults.timeout = 200000;
- axio.defaults.withCredentials = true;
原理同一,仍然失败了
4:还有的兄弟说,后端也要配置:
【Access-Control-Allow-Credentials】要为true
【Access-Control-Allow-Origin】设置允许访问的IP不能为【*】,会跟withCredentials=true冲突
于是有了下列的控制:
4-1:只允许自己的前端服务器访问:
- import java.util.Arrays;
- import java.util.HashSet;
- import java.util.Set;
-
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.stereotype.Component;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- @Component
- public class CorsInterceptor implements HandlerInterceptor {
-
- public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
- throws Exception {
-
- // 设置允许多个域名请求
- String[] allowDomains = {
- "http://localhost:3010"
- };
- Set<String> allowOrigins = new HashSet<String>(Arrays.asList(allowDomains));
- String originHeads = httpServletRequest.getHeader("Origin");
- if(allowOrigins.contains(originHeads)){
- //设置允许跨域的配置
- // 这里填写你允许进行跨域的主机ip(正式上线时可以动态配置具体允许的域名和IP)
- httpServletResponse.setHeader("Access-Control-Allow-Origin", originHeads);
- }
-
- httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
-
- httpServletResponse.setHeader("Access-Control-Allow-Headers",
- "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
-
- httpServletResponse.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
-
- httpServletResponse.setHeader("X-Powered-By", "Jetty");
-
- String method = httpServletRequest.getMethod();
- System.out.println(method);
- if (method.equals("OPTIONS")) {
-
- httpServletResponse.setStatus(200);
-
- return false;
- }
- return true;
- }
-
- public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
- ModelAndView modelAndView) throws Exception {
-
- }
-
- public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
- Object o, Exception e) throws Exception {
-
- }
- }
4-2:允许所有前端服务器访问
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
-
- import org.springframework.stereotype.Component;
- import org.springframework.web.servlet.HandlerInterceptor;
- import org.springframework.web.servlet.ModelAndView;
-
- @Component
- public class CorsInterceptor implements HandlerInterceptor {
-
- public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
- throws Exception {
- String originHeads = httpServletRequest.getHeader("Origin");
-
- httpServletResponse.setHeader("Access-Control-Allow-Origin", originHeads);
-
- httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
-
- httpServletResponse.setHeader("Access-Control-Allow-Headers",
- "Content-Type,Content-Length, Authorization, Accept,X-Requested-With");
-
- httpServletResponse.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
-
- httpServletResponse.setHeader("X-Powered-By", "Jetty");
-
- String method = httpServletRequest.getMethod();
- System.out.println(method);
- if (method.equals("OPTIONS")) {
-
- httpServletResponse.setStatus(200);
-
- return false;
- }
- return true;
- }
-
- public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
- ModelAndView modelAndView) throws Exception {
-
- }
-
- public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
- Object o, Exception e) throws Exception {
-
- }
- }
全部都尝试了,然而并没有什么用。
5:最好想啊想,想啊想,会不会是前端工程的问题呢
于是在controller中加了一个测试方法,由于后端需要权限验证
系统未登录前,在浏览器新开一个窗口直接访问,是带cookie的:
登陆后进行在浏览器直接访问,也是带cookie的:
于是有一点眉目了,总结如下:
1:不通过前端工程调用,直接从浏览器访问,非前端工程的ajax/axios等方法调用后端,能携带cookie
2:用本地的前端服务,使用axios等调用后端,不携带cookie
于是,把本地的服务和部署在服务器的服务进行比较:
本地前端服务,访问后端,没有cookie:
惊喜来了,服务器前端服务,访问后端,带Cookie
这就有可能是环境问题了,,,
于是去一番百度谷歌,,,只找到一篇有些类似:
于是只能自己想啊想,想啊想,想起来不带cookie的请求头都有一个【Provisional headers are shown】警告,如下:
又是一顿搜索,下面这个兄弟,说的好啊,虽然没解决我的问题:
想起来我们前端的那个兄弟,好像说过加了一个设置,不缓存请求的资源,每次都去服务器取最新的,会不会是这个问题呢,被设置了开发环境和生产环境的策略不一致?虽然希望渺茫,还是去试了试
关键代码如下:
试了几遍,还是老样子,说明不是这个问题
又找啊找,找啊找,突然想起来,服务器上是用的Docker镜像,前工程用了Nginx做反向代理,应该就是这个原因,又在网上找到两篇文字,发现这两个老哥说的挺对的:
老哥一:
修改项目目录,添加一个XXX的文件夹,把开发环境的需要的静态资源和页面文件放到XXX文件夹下,开发环境下访问项目地址改成http://localhost:8485/XXX。显然这个方案有缺陷,如果cookie path 改变,我们又需要再次改变项目目录结构,可能还需要修改webpack配置(或者其他打包配置)
2:nginx 代理的方式
3:webpack-dev-server 解决方案
关键思路如上:想多了解可看链接:https://segmentfault.com/a/1190000013753896
老哥二:
关键思路如上:想多了解可看链接:https://www.jianshu.com/p/cadab71987d2
所以,,,,今天就到这了,明天加个代理服务试试,应该可以解决问题
后续:果然如此:
package.json中加了一个代理,代理后端地址,解决问题
当然,也可以用Nginx做代理,访问前端和后端
也可以,使用zuul做网关代理,所有工程的访问,先到zuul,再由zuul转发到各自服务,
以上方案都可以,请各位八仙过海,各显神通
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。