【问题标题】:How to make a POST request to Stripe endpoint without CORS preflight如何在没有 CORS 预检的情况下向 Stripe 端点发出 POST 请求
【发布时间】:2019-07-12 00:21:06
【问题描述】:

尝试向 Node 中的 Stripe 端点发出基本 POST 请求:

const https = require('https');
const options = {
  hostname: 'connect.stripe.com',
  port: 443,
  path: '/oauth/token',
  method: 'POST',
  headers: { 
    'Content-Type': 'application/x-www-form-urlencoded' 
  }
}

const req = https.request(
  options, res => 
    res.on('data', d => 
      process.stdout.write(d))
)
req.write(data) // client_secret=stripe_sk&grant_type=authorization_code...
req.end()

响应

Failed to load https://connect.stripe.com/oauth/token:
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:3000' is therefore not allowed access. 
The response had HTTP status code 400.  If an opaque response serves your needs, 
set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

server.js

const express = require('express');
const next = require('next');
const nextI18NextMiddleware = require('next-i18next/middleware');
const nextI18next = require('./i18n');
const app = next({ dev: process.env.NODE_ENV !== 'production' });
const routes = require('./routes');
const handler = routes.getRequestHandler(app);

(async () => {
    await app.prepare();
    const server = express();
    nextI18NextMiddleware(nextI18next, app, server);
    server.get('*', (req, res) => handler(req, res));
    await server.listen(3000);
    console.log('Ready on http://localhost:3000');
})();

胡乱猜测

看起来有些东西在默默地修改标题,它不是一个简单 POST,而是一个带有一些额外标题的 POST,这反过来又会触发 CORS preflight 规则。
使用 Postman 我得到了预期的结果,问题出在标题中。

如何了解影响我的 POST 请求的因素? 任何提示将不胜感激!

HTTP 303

Request URL: https://connect.stripe.com/oauth/token
Request Method: GET
Status Code: 303 
Remote Address: 54.187.119.242:443
Referrer Policy: strict-origin-when-cross-origin
content-length: 0
content-security-policy: 
location: https://connect.stripe.com/login?redirect=%2Foauth%2Ftoken
referrer-policy: strict-origin-when-cross-origin
request-id: 1550537522-mreq_9XV0Kp3XVIJYPq
server: nginx
status: 303
strict-transport-security: max-age=31556926; includeSubDomains; preload
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-ua-compatible: IE=Edge,chrome=1
Provisional headers are shown
DNT: 1
Referer: http://localhost:3000/
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36

OPTIONS 请求

Request URL: https://connect.stripe.com/oauth/token
Request Method: OPTIONS
Status Code: 303 
Remote Address: 54.187.119.242:443
Referrer Policy: no-referrer-when-downgrade
content-length: 0
content-security-policy: default-src 
location: https://connect.stripe.com/login?redirect=%2Foauth%2Ftoken
referrer-policy: strict-origin-when-cross-origin
request-id: 1550537522-mreq_9XV0Kp3XVIJYPq
server: nginx
status: 303
strict-transport-security: max-age=31556926; includeSubDomains; preload
x-content-type-options: nosniff
x-frame-options: SAMEORIGIN
x-ua-compatible: IE=Edge,chrome=1
Provisional headers are shown
Access-Control-Request-Headers: access-control-allow-headers
Access-Control-Request-Method: POST
DNT: 1
Origin: http://localhost:3000
Referer: http://localhost:3000/profile/edit?code=ac_EYThaA5LNla8&state=35N1UGuPHac9
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36

【问题讨论】:

  • 使用浏览器开发工具中的网络窗格检查预检 OPTIONS 请求。查看 Access-Control-Request-Headers 请求标头的值。这将告诉您哪些标头正在触发浏览器发出 OPTIONS 请求。然后找出前端代码的哪一部分导致添加任何标头。
  • 这意味着在你的前端代码的某个地方,你有代码试图向请求添加一个“访问控制允许标头”请求标头。或者你有一个浏览器扩展正在添加它。无论哪种方式,都是错误的,因为 access-control-allow-headers 是响应头,而不是请求头。它不应该在请求中发送。
  • 如果您在客户端执行请求,几乎总是会发生此错误。您不能在客户端执行该请求,因为它使用您的 Secret API 密钥,并且必须在服务器端完成
  • 我不确定你的意思。该请求将来自您的代码服务器端,您不会在浏览器中运行它。
  • 这实际上是最近添加到条带节点库中的,尽管看起来文档还没有完全赶上。这是一个如何使用它的示例:github.com/stripe/stripe-node/blob/master/test/resources/…

标签: node.js http cors stripe-payments


【解决方案1】:

您需要将Access-Control-Allow-Origin 设置为*

对于 Firebase Cloud Functions,您可以这样做...

res.header('Content-Type', 'application/json');
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'Content-Type');
if (req.method === 'OPTIONS') {
res.status(204).send('');
}

但是,我不确定您使用的是哪个服务器,所以我不能给您确切的代码。

【讨论】:

  • 不知道谁反对这个答案。我在互联网上只能找到设置 Origin 的建议:*.但它不起作用。
  • 对不起,我不熟悉那个服务器。我希望我能提供更多帮助。
猜你喜欢
  • 1970-01-01
  • 2017-09-15
  • 2018-08-16
  • 1970-01-01
  • 2021-05-26
  • 2022-07-18
  • 1970-01-01
  • 2016-06-15
  • 2014-07-13
相关资源
最近更新 更多