【问题标题】:Unable to access form data on serverside无法访问服务器端的表单数据
【发布时间】:2019-06-03 17:22:25
【问题描述】:

我正在从前端发出一个 put 请求,我一直在使用 XMLHttpRequest and FormData API 请求,但服务器端我不会得到像 req.params, req.body and req.query 这样的任何数据,都是空的

前端代码

var reportSub = () => {

        var report = document.getElementById('report');

        var formData = new FormData(report)



    let xhr = new XMLHttpRequest();

    xhr.onreadystatechange = () => {
        if (xhr.readyState === 4 && xhr.status === 200) {
            console.log(xhr.response)
        }
    }

    var queryString = new URLSearchParams(formData);

    xhr.open("PUT", '/threads/edit', true);
    xhr.setRequestHeader('Content-Type', 'multipart/form-data');
    xhr.send(queryString)

}
 var reportsub = document.querySelector('#repsub');
 reportsub.addEventListener("click",(e)=>{
        e.preventDefault();

        reportSub();
    })

服务器端代码


router.put('/threads/edit',(req,res)=>{

    let board = req.body.board;
    let id = req.body.id;

    console.log(req.query,req.body)

    Board.findById({_id: ObjectId(id)},(error,data)=>{

      if(error)
          res.send(error)

      if(data!==null){
        data.Reprot = true;
        data.save((error,sd)=>{

          if(error)
              res.send(error)

           res.send(sd);   
        })
      } 
      else{
        res.send({"Error":"Id does not exist "})
      }   
    })
})

有一种解决方案是您在 url 中添加数据,该数据再次硬编码每个变量和您必须传递的数据。 所以我想使用 FormData 接口来发送数据。

【问题讨论】:

  • 您可以使用.send直接发送FormData。尝试使用xhr.send(formData)。只有req.body 应该包含所需的数据。 URLSearchParams 不能从 FormData 构造,但也可用于实现此目的:
  • 我已经尝试过了,它会给我empty object
  • #report 是表单元素吗?
  • 是的。我认为这里与请求标头有关
  • 您是否使用任何中间件来解析请求,例如express.json()

标签: javascript express xmlhttprequest


【解决方案1】:

我认为您缺少用于解析 FormData 请求的库。您也可以使用 JSON 发送数据,因为它是纯文本的,这将简化解析。一个最小的示例可能如下所示:

server.js

const express = require("express");
const multer = require("multer");
const upload = multer();
const app = express();

app.use(express.static('public'))

app.post('/data', upload.none(), function (req, res) {
    console.log(req.body.favoriteNumber);
    res.send('42 is the only real choice');
});

app.listen(3000, function () {
    console.log('App listening on port 3000!');
});

public/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>
    <form id="textForm">
        <p>Your favorite number:</p>
        <input type="text" value="42" name="favoriteNumber" />
    </form>
    <button id="send">Send</button>
    <script>
        const sendButton = document.getElementById("send");
        const form = document.getElementById("textForm");
        sendButton.addEventListener("click", () => {
            let xhr = new XMLHttpRequest();

            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4 && xhr.status === 200) {
                    console.log(xhr.response);
                }
            }

            const formData = new FormData(form);
            xhr.open("POST", '/data', true);
            xhr.send(formData);
        })
    </script>
</body>

</html>

您不必手动设置标题。它是自动设置的,并且确实包含boundary - 一个您在编写应用程序时无法知道的参数。标头可能如下所示:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryuzeaYvzY77jzcFeA

【讨论】:

    猜你喜欢
    • 2014-07-20
    • 2013-12-27
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 2013-05-12
    • 2019-07-01
    • 1970-01-01
    相关资源
    最近更新 更多