首页 > 解决方案 > 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 脚本。

标签: node.jshttp

解决方案


首先,我认为没有必要同时使用httprequest模块。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);
});

推荐阅读