node.js - nodejs请求发布大json失败
问题描述
我正在尝试将大型 json 发布到 http 服务器(实际上是 grafana 服务器):
这是我的代码:
const http = require('http')
const request = require('request')
const fs = require('fs')
const opts = {
hostname: 'myip',
port: 3000,
path: '/api/dashboards/uid/KPEiIQVWk',
method: 'GET',
timeout: 5000,
headers : {
'Authorization' : 'Bearer ********************************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json'
}
}
const req = http.request(opts, res => {
console.log(`Fetch: statusCode: ${res.statusCode}`)
var origin = ''
res.on('data', d => {
origin += d
})
res.on('end', function(){
dash = JSON.parse(origin)
dash.dashboard.panels.forEach(p => {
if(p.id == 26){
fs.readFile(__dirname + '/grafana/pm/branch-graph.html','utf-8', function(err, newPanel){
if(err){
console.log(err)
}
p.content = newPanel
const fresh = JSON.stringify(dash)
const updateOptions = {
uri: 'http://myip:3000/api/dashboards/db',
method: 'post',
headers : {
'Authorization' : 'Bearer *************************',
'Accept' : 'application/json',
'Content-Type' : 'application/json',
'Content-length' : fresh.length
},
json: fresh
}
fs.writeFile('tmp.json', fresh, function(err){
if(err){
console.error(err)
}
})
request(updateOptions, function(error, response, body){
console.log(`update: statusCode=${response.statusCode}`)
console.log(`update: ${body}`)
})
})
}
})
})
})
req.on('error', error => {
console.error(error)
})
req.on('timeout', () => {
req.abort()
})
req.end()
如您所见,我首先获取 grafana 仪表板的源代码,然后进行一些更新,然后将其发布回 grafana 服务器。但总是得到 400 错误。奇怪的是,如果我将 json 转储到文件并使用 curl 发布,它会起作用。
curl -vH "Authorization: Bearer $TOKEN" -H "Expect:" -d @tmp.json -H "Content-Type:application/json" http://myip:3000/api/dashboards/db
整个 json 大约 40000+ 字节。对此有任何提示吗?我对nodejs不是很熟悉。我只是想写一些 CI 脚本。
解决方案
首先,我认为没有必要同时使用http
和request
模块。http
是一个内置于 nodejs 中的模块,并且request
是一个 npm 包。
我推荐你使用 npm request 包,因为它更容易。您可以在此处阅读其文档:https ://www.npmjs.com/package/request#http-authentication
其次,您传递给请求模块的选项格式不正确,我认为这就是它不起作用的原因。使用您当前的代码,我会console.log('POST error', error);
打印出错误。request
下面提出了该模块的正确选项。
const options = {
url: 'https://myip:3000/api/dashboards/db',
body: fresh, // the json from the fs.read callback
auth: {
'bearer': 'bearerToken'
},
json: true // from docs: If json is true, then body must be a JSON-serializable object.
}
request.post(
options,
(err, httpResponse, body) => {
console.log(err, body);
});
推荐阅读
- python-3.x - ' ValueError: max() arg is an empty sequence ' 在 PyCharm 中使用 plt.show() 时
- python - 从字符串 pandas python 创建一个数据框
- curl - 如何在 POST 请求中添加 UTF-8 编码
- devexpress - 为什么 Dev express ReportService 保存类但加载字节数组?
- angular - 如何在方法中注入服务?
- java - 复杂模式匹配
- r - 如何从向量中创建一个包含一列和列名的小标题?
- ruby-on-rails - 在 Ruby 中将蛇案例转换为普通句子
- javascript - 将 html 页面保存到 .doc 中适用于 firefox,不适用于 ie - 如何解决?
- audio - 嵌入式 Linux 安装 ALSA 并播放音频 `aplay` 问题