【问题标题】:POSTing from Angular to Node. Getting empty body on node从 Angular 发布到节点。在节点上获取空体
【发布时间】:2021-12-03 22:28:00
【问题描述】:

我将 Angular 中的两个字段发布到 NodeJs 端点。

我通常在body上发帖,在Node上一切都很完美,但这次,我必须发一个表单来上传文件。

这是我发布表单数据的代码(Angular 端):

var APIURL = sessionStorage.getItem('endPoint') + "profile/updateeocoverage"; 
let formData = new FormData();
formData.append("data", JSON.stringify(this.payLoad));
if (this.eofile) {
  formData.append("myfile", this.eofile, this.eofile.name);
}
this.httpClient.post(APIURL,  formData).subscribe(
  result => {
  ....

我的问题是我总是按如下方式在节点检索正文:

router.post('/updateeocoverage', async   (req, res, next) => {
    console.log(req.body)
    return;
    ....

但是使用我现在在 Angular 中使用的方法,req.body 正在检索 {}

是POST错了,还是Node侧的路由器错了?

谢谢。

为遇到此问题的人提供以下 PABLO 答案的更新(已提供解决方案):

使用 Multer 解决了这个问题,但正如他所说,需要一些解决方法来设置文件名,但最重要的是需要对用户进行身份验证,所以:

const multer = require('multer')
const path = require('path')

为了对用户进行身份验证,我在标头上发送身份验证参数。将其作为 formdata.append 发送对我不起作用。这将设置 true 或 false 来上传文件,否则任何人都可以将任何内容上传到路由:

async function authenticateUser(req, file, cb) {
    let tempcred = JSON.parse(req.headers.data)
    let credentials = tempcred.credentials;
    let userData = await utils.isValidUser((credentials), false);
    if (userData.isValid == false) {
        cb(null, false)
        return;
    }
    else {
        cb(null, true)
    }
}

然后,由于 Multer 使用随机名称上传文件,并且我需要使用用户 ID 名称和文件扩展名保存它,所以我执行以下操作:

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, 'uploads/eofiles/')
    },
    filename: async function (req, file, cb) {
        let tempcred = JSON.parse(req.headers.data)
        let credentials = tempcred.credentials;
        let userid = await utils.decrypt(credentials.userid, process.env.SECRET);
        cb(null, userid + path.extname(file.originalname))
    }
});

最后,我声明了用于 Multer 的上传变量:

var upload = multer({ storage: storage, fileFilter: authenticateUser })

并设置路由器:

router.post('/updateeofile', upload.single("myfile"), async (req, res, next) => {
let filename = req.file.filename //gets the file name
...
...
do my stuff, save on database, etc
...
...
});

为了记录,“myfile”是输入文件的id。

这就是我从 Angular 上传文件的方式:

var APIURL = sessionStorage.getItem('endPoint') + "eoset/updateeofile";    
    const httpOptions = {
      headers: new HttpHeaders({
        'data': `${JSON.stringify(this.payLoad)}`
      })
 };
 let formData = new FormData();
    if (this.eofile) {
      formData.append("myfile", this.eofile, this.eofile.name);
    }
    this.httpClient.post(APIURL, formData, httpOptions).subscribe(
      result => {
...
...
...
 },
      error => {

});

我今天在这上面花了 6 个小时。我希望这可以帮助您并节省您一些时间。

【问题讨论】:

    标签: node.js angular typescript


    【解决方案1】:

    首先要做的是在发出请求之前确保正文不是空的,所以在请求之前做一个console.log:

    console.log(formData);
    this.httpClient.post(APIURL,  formData).subscribe(
      result => {
      ....
    

    之后,如果body填充正确,尝试把body这样放在request方法上:

    this.httpClient.post(APIURL,  {formData})
    

       this.httpClient.post(APIURL,  {
         "field1": formData.field1,
         ...
    })
    

    如果这两件事都不能解决您的问题,则可能是您在后端有问题

    【讨论】:

    • 嗨,费利佩。它不是空的,我可以用 .NET 很好地阅读它,看起来问题出在 NODE 上。
    • 哇,您的第二种方法效果很好。我的问题是为什么我可以在 .NET 中阅读它,但不能在 NODE 上阅读。现在弄清楚如何添加文件。
    • 其实我不知道为什么会这样,但我认为是节点解析请求的时候,但我很高兴这对你有用:)
    • 我很难用你的方法添加文件,Felipe 有什么建议吗?谢谢!
    【解决方案2】:

    尝试使用 Multer

    npm 计算

    const multer  = require('multer')
    const upload = multer({ dest: 'uploads/' })
    router.post('/updateeocoverage', upload.single('myfile'), function (req, res, next) {
        res.json(JSON.parse(req.body.data))
      })
    

    您需要指明目标文件夹(第 2 行)并计算出文件名、扩展名等。

    【讨论】:

    • 效果很好。它写了一个随机名称,但我会弄清楚如何更改文件名。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2018-01-21
    • 1970-01-01
    • 2018-08-08
    • 2015-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多