CORS跨域请求问题: 服务器响应携带Set-Cookie响应头, 客户端(服务器)无法将cookie存储进浏览器application中 (已解决)

一. 跨域环境介绍:

后端: servlet 实现, 使用过滤器让响应携带跨域响应信息(本问题和后端如何设置跨域响应头无任何关系);

        运行地址: http://localhost:8080

前端: vue + axios(如果你使用原生ajax/fetch, 此方法也可行);

        运行地址: http://localhost:9091

二. 代码环境:
1. CORSFilter过滤器代码: 
@WebFilter("/*")
public class CORSFilter extends HttpFilter {
    @Override
    protected void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws IOException, ServletException {
        System.out.println("跨域设置...");
        //解决跨域问题
        res.setHeader("Access-Control-Allow-Origin", "http://localhost:9091");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        res.setHeader("Access-Control-Max-Age", "3600");
        res.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type");
        res.setHeader("Access-Control-Allow-Credentials", "true");
        chain.doFilter(req, res);
    }
}
2. 前端请求代码: 
<template>
  <div id="app">
    <button @click="login">登录</button>
    <button @click="getPageOne">获取第一页数据</button>
  </div>
</template>

<script>
import axios from "axios";
export default {
  name: "App",
  components: {},
  data() {
    return {
      userInfo: {
        name: "admin",
        password: "111111",
      },
    };
  },
  methods: {
    async login() {
      await axios
        .post(
          "http://localhost:8080/moveHouse/user/login?" + Date.now(),
          JSON.stringify(this.userInfo)
        )
        .then((res) => {
          console.log(res);
        });
    },

    async getPageOne() {
      await axios.get("http://localhost:8080/moveHouse/booking/selectPage?pageSize=2&pageNum=1").then(res => {
        console.log(res);
      })
    }
  },
};
</script>
<style>
</style>

三. 问题复现

请求login服务后, 响应中会返回cookie信息, 如下:

但是, 客户端并没有将cookie存进浏览器的本地cookie中, 如下:

四. 问题解决

几经周折(真的很周折), 终于解决了这个问题!

是什么原因导致客户端不存储cookie呢? 很显然就是客户端的问题? 在众多的帖子中我发现了原生ajax中XMLHttpRequest对象有一个withCredentials静态属性, MDN 这样介绍此属性:

绿色框描述表达的意思是: withCredentialsfalse时, 客户端将不保存响应携带的cookie, 而且默认值还是false; 我醍醐灌顶!

Axios请求库, 就是根据原生ajax进行封装的, 所以axios也具备这样一个属性, 且和XMLHttpRequest的默认值一样,同样为false

所以我在created钩子处,设置了axios的默认配置中的withCredentials属性为true: 如下: 

再次发起登录请求, cookie已经存储到浏览器中, 如下: 

提两点:

1. 如果不设置withCredentials为true, 那么请求同样不会携带浏览器存储的cookie到服务器, 尽管你的cookie是存在的; 比如说你使用原生ajax发请求, 只能局部设置withCredentials的时候, 很容易出现这样的情况-----能拿到cookie, 但是后续请求无法携带cookie, 那么你应该检查你的后续请求是否设置了"允许携带";

2. 我使用axios.defaults.withCredentials是在本Vue组件内设置生效了, 组件内方法所有的请求是可以生效的, 其他组件局部引入axios设置后才可行. 推荐全局引入, 省去不少麻烦;

JavaJavaScript使用CORS跨域资源共享)解决跨域问题的步骤如下: 1. 在Java后端设置CORS支持:在处理跨域请求Java代码,需要设置响应以启用CORS。可以通过在响应对象设置以下响应字段来实现: ```java response.setHeader("Access-Control-Allow-Origin", "http://example.com"); // 允许特定的源访问 response.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); // 允许的HTTP方法 response.setHeader("Access-Control-Allow-Headers", "Content-Type"); // 允许的请求 response.setHeader("Access-Control-Allow-Credentials", "true"); // 是否允许发送Cookie response.setHeader("Access-Control-Max-Age", "3600"); // 预检请求的有效期 ``` 2. 在JavaScript前端发起跨域请求:在发送跨域请求JavaScript代码,需要设置请求以指示该请求是一个跨域请求。可以使用XMLHttpRequest或fetch API来发送请求,并在请求添加以下字段: ```javascript fetch('http://api.example.com/data', { method: 'GET', headers: { 'Content-Type': 'application/json', 'Origin': 'http://example.com' // 请求源 }, credentials: 'include' // 发送Cookie }) .then(response => { // 处理响应 }) .catch(error => { // 处理错误 }); ``` 通过以上步骤,Java后端设置了CORS支持,允许特定源访问资源,并在JavaScript前端发送跨域请求时设置了请求,指示该请求是一个跨域请求。这样就可以解决跨域问题。请注意,实际应用需根据自己的需求和安全考虑行适当的配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值