【问题标题】:How do I make a http post request in Node based off of a curl request?如何根据 curl 请求在 Node 中发出 http post 请求?
【发布时间】:2021-01-02 22:22:13
【问题描述】:

Paypal 说要发出以下 curl 请求

  curl -v POST https://api-m.sandbox.paypal.com/v1/oauth2/token \
  -H "Accept: application/json" \
  -H "Accept-Language: en_US" \
  -u "CLIENT_ID:SECRET" \
  -d "grant_type=client_credentials"

但是,我想通过 HTTP 请求来实现。我尝试了以下方法:

const HTTP = require('http')
const data = JSON.stringify({
    paypalclientid:paypalsecretid,
    "grant_type": "client_credentials",
})
const options = {
    host: 'api-m.sandbox.paypal.com',
    port: 80,
    path: '/v1/oauth2/token',
    method: 'POST',
    headers: {
        'Accept': 'application/json',
        "Accept-Language": "en_US"
    }
}
const req = http.request(options, res => {
    console.log(`statusCode: ${res.statusCode}`)

    res.on('data', d => {
        process.stdout.write(d)
    })
})

req.on('error', error => {
    console.error(error)
})

req.write(data)
req.end()

我得到了以下信息:

<HTML><HEAD>
<TITLE>Access Denied</TITLE>
</HEAD><BODY>
<H1>Access Denied</H1>
 
You don't have permission to access "http&#58;&#47;&#47;api&#45;m&#46;sandbox&#46;paypal&#46;com&#47;v1&#47;oauth2&#47;token" on this server.<P>
Reference&#32;&#35;18&#46;9ce33e17&#46;1609625956&#46;708d702f
</BODY>
</HTML>

这就是你执行普通 GET 请求时得到的结果。

【问题讨论】:

  • curl 帮助页面:-u, --user &lt;user:password&gt; Server user and password。您在帖子正文中传递它,而不是作为 HTTP 用户/密码。
  • 附带说明,我建议您使用一个库来处理 http 请求,默认的 http 模块并不完全是用户友好的。我会推荐node-fetch,因为它实现了与浏览器相同的api。
  • 在 curl 请求中,使用了https,但您在options 中定义了port: 80https 的默认端口是 443

标签: javascript node.js http paypal request


【解决方案1】:
  • 您需要对您的凭据进行 base64 编码并将其发送到 Authorization 标头中。
  • 您需要通过 https 发出请求。
  • 您需要对内容进行表单编码。

这是一个适用于有效userpass 的示例:

const https = require('https')

const data = `grant_type=client_credentials`;
const user = 'your client id';
const pass = 'your secret';
const authorization = `Basic ` + Buffer.from(`${user}:${pass}`).toString(`base64`);

const options = {
  hostname: 'api.paypal.com',
  port: 443,
  path: '/v1/oauth2/token',
  method: 'POST',
  headers: {
    'Authorization': authorization,
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': data.length
  },
}

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', d => {
    process.stdout.write(d)
  })
})

req.on('error', error => {
  console.error(error)
})

req.write(data)
req.end()

【讨论】:

  • 在使用请求库时,无需自己对字符串进行 base64 编码并构建基本授权标头,只需一行即可完成。新的api-m 端点也更快
【解决方案2】:

看来你需要basic authentication:

const options = {
    auth: 'CLIENT_ID:SECRET',
    ...

您还应该使用端口 443 (HTTPS),以及:

    'Content-Type': 'application/x-www-form-urlencoded'

对于这个特定的令牌请求(几乎所有其他 PayPal REST 端点都采用application/json

【讨论】:

    猜你喜欢
    • 2015-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-22
    相关资源
    最近更新 更多