【问题标题】:Not Receiving Set-Cookie Header with axios post request未使用 axios 发布请求接收 Set-Cookie 标头
【发布时间】:2019-07-05 21:39:06
【问题描述】:

我有一个 PHP 脚本,如果直接在浏览器(或邮递员)中调用,它会成功返回一些简单的标头以及 set-cookie 标头。我可以从 chrome devTools 中读取类似的响应标头。但是一旦我通过 Axios 调用它,set-cookie 标头就不会出现,并且浏览器中也没有保存 cookie。

我尝试了不同的方法,例如更改服务器端的响应标头并在 axios 中使用“withCredentials: true”,但没有任何效果。我什至没有收到错误或任何与 cors 相关的问题。

PHP:

header("Access-Control-Allow-Origin: http://localhost:8080");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST, GET");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
header("Access-Control-Max-Age: 99999999");
setcookie("TestCookie", "Testing", time() + 3600, "/", "localhost", 0);
die();

JS:

Vue.prototype.$http = axios.create({
    baseURL: XYZ,
    withCredentials: true
})

所以我的第一个问题是为什么直接调用php脚本时会出现header?以及如何归档以通过axios获取标题?

【问题讨论】:

  • 您确定这不仅仅是因为浏览器设置阻止了第 3 方 cookie 吗? stackoverflow.com/a/16634941/10955263
  • 好吧,我尝试使用相同的浏览器直接调用脚本并且它有效。或者 axios 是否会通过请求阻止某些内容?刚刚检查了您的链接:Chrome 也没有阻止第三方 Cookie
  • “好吧,我尝试用同一个浏览器直接调用脚本,它成功了” - 如果你直接调用它,它不是第 3 方……
  • 抱歉,刚刚更新了我的评论。我没有阻止第三方 cookie

标签: javascript php vue.js axios


【解决方案1】:

可能 cookie 是“httpOnly”,这意味着客户端 javascript 无法读取它。 因此它没有显示在 chrome cookie 部分。 在 Mozilla 中测试相同的请求,header 会出现。

【讨论】:

  • 我使用 axios 创建了一个独立的命令行脚本,但我也没有在标题中收到“Set-Cookie”。使用 curl 的相同发布请求确实在标头中显示了 Set-Cookie 值。 Postman 还接收 Set-Cookie 标头。我尝试使用 javascript Fetch 也没有显示标题。这让我发疯了。
【解决方案2】:

这可能不适用于您的情况,但我在这个独立的 nodejs 脚本中使用 axios 时遇到了同样的问题。

const config = {
    url: 'https://remote.url/login',
    method: 'post',        
    headers: {
        'content-type': 'application/x-www-form-urlencoded',
    },
    data: qs.stringify({
        'email': username,
        'password': pwd
    })
}

axios(config).then(res => {
    console.log(res.headers);
}).catch(err => {
    console.log(err);
})

这返回了 http 状态 200,但标头中没有 set-cookie。使用 curl 正确检索了标头,但状态代码为 302

将以下配置选项添加到 axios 后:

maxRedirects: 0,
validateStatus: function (status) {
    return status <= 302; // Reject only if the status code is greater than 302
  },

我在axios的response.header中收到了set-cookie

{
  server: 'nginx/1.16.1',
  date: 'Fri, 27 Dec 2019 16:03:16 GMT',
  'content-length': '74',
  connection: 'close',
  location: '/',
  'set-cookie': [
    'cookiename=xxxxxxxxxxxxxxxxxxxxx; path=/; expires=Sat, 26-Dec-2020 16:03:16 GMT'
  ],
  status: '302',
  'x-frame-options': 'DENY'
}

没有maxRedirects: 0我收到了我使用的远程url主页的html。

没有validateStatus,我在err.response.headers 对象中收到了set-cookie 标头。

【讨论】:

    【解决方案3】:

    对我来说,正在像这样添加 {withCredentials: true}:

    axios
    .post(url, {
        foo: foo,
        baz: baz,
        }, {withCredentials: true})
    .then(.............
    

    【讨论】:

      【解决方案4】:

      在我的情况下,网络面板显示响应具有“Set-Cookie”标头,但在 axios 中标头不会显示,并且正在设置 cookie。

      对我来说,分辨率是设置Access-Control-Expose-Headers 标头。

      解释:

      this comment 在 axios 存储库中的一个问题上,我被定向到了这个 person's notes,这导致我设置了 Access-Control-Expose-Headers header——现在 cookie 已在客户端中正确设置。

      因此,在 Express.js 中,我必须将 exposedHeaders 选项添加到我的 cors 中间件:

      const corsOptions = {
        //To allow requests from client
        origin: [
          "http://localhost:3001",
          "http://127.0.0.1",
          "http://104.142.122.231",
        ],
        credentials: true,
        exposedHeaders: ["set-cookie"],
      };
      
      ...
      
      app.use("/", cors(corsOptions), router);
      

      同样重要的是,在 axios 方面,我使用 withCredentials 配置来跟踪我想要包含 cookie 的 axios 请求。

      前/

      const { data } = await api.get("/workouts", { withCredentials: true });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-10-27
        • 2021-12-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-20
        • 2022-06-25
        • 1970-01-01
        相关资源
        最近更新 更多