【问题标题】:I'm having a CORS Prefetch Error 400 Bad Request我有一个 CORS 预取错误 400 错误请求
【发布时间】:2021-09-28 02:11:33
【问题描述】:

我正在我的本地开发服务器上运行一个 Vue 项目,它的 firebase 功能也在本地开发服务器上运行。每当我尝试向我的“beckend”发出获取请求时,都会收到 CORS 错误。

飞行前请求

OPTIONS /api/url HTTP/1.1
Host: localhost:5001
Connection: keep-alive
Accept: */*
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type
Origin: http://localhost:8080
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-site
Sec-Fetch-Dest: empty
Referer: http://localhost:8080/
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9

回复

HTTP/1.1 400 Bad Request
x-powered-by: Express
access-control-allow-origin: http://localhost:8080
access-control-allow-methods: POST, OPTIONS
access-control-allow-headers: Content-Type
content-type: application/json; charset=utf-8
content-length: 44
etag: W/"2c-1mdAJaORqKZ8xUSbM/cjasU4RC0"
date: Tue, 20 Jul 2021 14:40:25 GMT
connection: keep-alive
keep-alive: timeout=5

这是我的代码:

前端

fetch(/api/url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    currency: "usd",
    paymentMethodType: "card",
    amount: 1880,
  }),
}).then();

后台

exports.myFunctionName = functions.https.onRequest(async (req, res) => {
  const origin = req.headers.origin;

  if (ALLOWED_ORIGINS.includes(origin)) {
    res.setHeader("Access-Control-Allow-Origin", origin);
  }

  res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");

  const {paymentMethodType, currency, amount} = req.body;
    const params = {
      payment_method_types: [paymentMethodType],
      amount: +amount,
      currency: currency,
    };

  try {

   // Create a PaymentIntent with the amount, currency, and a payment method type.
   const paymentIntent = await stripe.paymentIntents.create(params);

    // Send publishable key and PaymentIntent details to client
    res.status(200).json({
      clientSecret: paymentIntent.client_secret,
    });
  } catch (e) {
    return res.status(400).json({
      error: {
        message: e.message,
      },
    });
  }
}

我似乎无法弄清楚这一点,我已经工作了几个小时。有人可以帮忙吗?

【问题讨论】:

  • 您没有显示决定返回“错误请求”的后端代码部分。只是添加标题的部分。
  • @RoddyoftheFrozenPeas 我更新了代码以显示函数的其余部分。然而,它甚至没有被运行,因为它失败了 CORS。这是获得 400 的预检 OPTIONS 请求
  • 不,因为await stripe.paymentIntents.create(params);(可能)出错,它返回 400 导致 cors 失败。 400 响应中的信息是什么?
  • @RoddyoftheFrozenPeas 没有发回响应数据。

标签: firebase vue.js google-cloud-functions cors


【解决方案1】:

问题是您的函数将预检请求视为实际的 POST 请求,但它们是分开的,不会同时发送。

浏览器自动发送OPTIONS 预检请求(没有正文)POST。您的函数尝试将不存在的主体参数从 OPTIONS 传递到 Stripe API,从而导致您的 catch 处理程序捕获异常,该处理程序以 400 响应。

浏览器可以发送POST请求之前的backend function should respond to OPTIONS with an ok status (e.g., 200)

exports.myFunctionName = functions.https.onRequest(async (req, res) => {

  // Handle preflight request
  if (req.method === "OPTIONS") {
    // allow `POST` from all origins for local dev
    res.set("Access-Control-Allow-Origin", "*");
    res.setHeader("Access-Control-Allow-Methods", "POST");
    return res.sendStatus(200);

  } else {
    // Handle `POST` request here...
  }
}

【讨论】:

    猜你喜欢
    • 2019-09-15
    • 2018-07-08
    • 2017-03-23
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-06
    相关资源
    最近更新 更多