在 Node.js 中使用 axios 发布表单数据

Posted

技术标签:

【中文标题】在 Node.js 中使用 axios 发布表单数据【英文标题】:Post form data with axios in Node.js 【发布时间】:2017-06-05 11:22:26 【问题描述】:

我正在 Postman 上测试 Uber API,并且能够成功发送带有表单数据的请求。当我尝试使用 Node.js 和 axios 库翻译此请求时,出现错误。

这是我的 Postman 请求的样子:

我得到的回复是: "error": "invalid_client"

这是我在 Node.js 和 axios 中所做的:

var axios = require("axios");

const config =  headers:  'Content-Type': 'multipart/form-data'  ;

axios.post('https://login.uber.com/oauth/v2/token', 
  client_id: '***',
  client_secret: '***',
  grant_type: 'authorization_code',
  redirect_uri: 'http://localhost:8080/',
  code: '***'
, config)
  .then(function(response) 
    console.log(response.data)
  )
  .catch(function(error) 
    console.log(error)
  )

当我这样做时,我会收到 400 响应。

我添加了 'multipart/form-data' 标头,因为我在 Postman 请求中填写了表单数据。如果没有标题,我会得到相同的结果。

我希望得到与 Postman 相同的响应,我的 Node.js 脚本中的配置变量有问题吗?

任何帮助将不胜感激!

【问题讨论】:

您似乎在 API 调用中发送了一个附加参数。当您发送附加参数时,您往往会收到此 Invalid Client 错误。 您是否尝试过使用querystring.stringify 传递数据?像这样:var querystring = require('querystring'); axios.post('http://something.com/', querystring.stringify( foo: 'bar' ); @KingJulien 将数据包装在查询字符串模块中这次并没有帮助我...... @KingJulien 这个querystring.stringify 为我工作。我以 dict 格式而不是字符串发送数据 【参考方案1】:

您也许可以使用Content-Type: 'application/x-www-form-urlencoded'。我遇到了与https://login.microsoftonline.com 类似的问题,它无法处理传入的application/json

var axios = require("axios");

axios(
  url: 'https://login.uber.com/oauth/v2/token',
  headers:  'Content-Type': 'application/x-www-form-urlencoded' ,
  data: `client_id=$encodeURIComponent('**')&client_secret=$encodeURIComponent('**')&grant_type=authorization_code&redirect_uri=$encodeURIComponent('http://localhost:8080/')&code=$encodeURIComponent('**')`
)
.then(function(response) 
  console.log(response.data)
)
.catch(function(error) 
  console.log(error)
)

您也可以使用函数来处理转换为 formUrlEncoded 的方式

const formUrlEncoded = x =>
   Object.keys(x).reduce((p, c) => p + `&$c=$encodeURIComponent(x[c])`, '')

var axios = require("axios");

axios(
  url: 'https://login.uber.com/oauth/v2/token',
  headers:  'Content-Type': 'application/x-www-form-urlencoded' ,
  data: formUrlEncoded(
     client_id: '***',
     client_secret: '***',
     grant_type: 'authorization_code',
     redirect_uri: 'http://localhost:8080/',
     code: '***' 
  )
)
.then(function(response) 
  console.log(response.data)
)
.catch(function(error) 
  console.log(error)
)

【讨论】:

another question提到的'qs' npm包可以做url编码。【参考方案2】:

截至 2017 年 6 月 10 日,axios 库不支持在 Node.js 中发布表单数据。这是 GitHub 上的问题 - https://github.com/mzabriskie/axios/issues/789

我们遇到了类似的问题,因此决定切换到request 库。

【讨论】:

这仍然是问题吗,因为我无法通过设置data 参数来发布表单数据,与request 一起工作正常 是的,我认为这个问题没有解决,他们已经用以下评论关闭了这个问题:github.com/axios/axios/issues/789#issuecomment-568146899【参考方案3】:

要使用 Content-Type application/x-www-form-urlencoded 发送数据,请使用此 sn-p:

const axios = require("axios");
const data = 
  username: "hello",
  password: "byby",
;
const body = new URLSearchParams(data);
axios
  .post("https://api.zipwhip.com/user/login", body)
  .then((res) => console.log(res.data));


【讨论】:

【参考方案4】:

从错误看来,您的 client_id 或 client_secret 不正确。启用调试并共享原始请求/响应(在过滤掉凭据之后)。

【讨论】:

【参考方案5】:

这不是真的!您可以使用 nodejs 通过 axios 发布数据。我已经做了。问题是,如果您在服务器端使用 php,您需要注意一个陷阱。 Axios 以 JSON 格式发布数据(内容类型:application/json) 使用此内容类型时,不会填充 PHP 的标准 $_POST 数组。所以它永远是空的。为了获取通过 json 请求发送的 post 参数,您需要使用 file_get_contents("http://php://input") 。

服务器端的一个简单 PHP 脚本是:

if($_SERVER['REQUEST_METHOD']==='POST' && empty($_POST)) 
 $_POST = json_decode(file_get_contents('http://php://input'));

使用此方法可以避免 formData 依赖。您可以直接从 node.js 发布数据。

【讨论】:

如果发布表单数据是您唯一的选择。也就是说,如果您无权访问 API?请参阅@Reid Evans 的回答

以上是关于在 Node.js 中使用 axios 发布表单数据的主要内容,如果未能解决你的问题,请参考以下文章

axios的使用与跨域问题的解决

使用 Axios 在 Node.js 中克服 Pending Promise 并完成构建 JSON

如何在 node.js 中使用 axios 循环许多 http 请求

使用 AXIOS (Node.js) 在请求之间保留 cookie

React 开发服务器不代理表单提交

Node.js / Axios 不会连接到 localhost