Postman 帖子请求有效,但 ajax 帖子无效。一遍又一遍地检查客户端 js

Postman post request works but ajax post does not. Have checked client side js over and over

提问人:Jack Surtees 提问时间:2/8/2019 最后编辑:NimanthaJack Surtees 更新时间:11/10/2023 访问量:3338

问:

我的问题是我有一个端点来创建一个项目,当我使用 Postman 发送 POST 请求时,它可以工作。我正在使用 node 和 express:

router.post("/", jwtAuth, (req, res) => {
  console.log(req.body);
  const requiredFields = ["date", "time", "task", "notes"];
  requiredFields.forEach(field => {
    if (!(field in req.body)) {
      const message = `Missing \`${field}\` in request body`;
      console.error(message);
      return res.status(400).send(message);
    }
  });
  Task.create({
    userId: req.user.id,
    date: req.body.date,
    time: req.body.time,
    task: req.body.task,
    notes: req.body.notes
  })
    .then(task => res.status(201).json(task.serialize()))
    .catch(err => {
      console.error(err);
      res.status(500).json({ message: "Internal server error" });
    });
});

当我使用 Postman 发送并使用正确的值记录 req 正文时,该端点有效。

但是当我发送 ajax 请求时,我的服务器代码将 req.body 记录为空对象 ('{}')。因为 Postman 有效,我相信问题出在我的客户端 javascript 上,但我就是找不到问题。我和其他人已经看了一百万次,但就是找不到问题所在。这是我的客户端 javascript:

//User submits a new task after timer has run
function handleTaskSubmit() {
  $(".submit-task").click(event => {
    console.log("test");
    const date = $(".new-task-date").text();
    const taskTime = $(".new-task-time").text();
    const task = $(".popup-title").text();
    const notes = $("#task-notes").val();
    $(".task-notes-form").submit(event => {
      event.preventDefault();
      postNewTask(date, taskTime, task, notes);
    });
  });
}

function postNewTask(date, taskTime, task, notes) {
  const data = JSON.stringify({
    date: date,
    time: taskTime,
    task: task,
    notes: notes
  });
//Here I log all the data. The data object and all its key are defined
  console.log(data);
  console.log(date);
  console.log(taskTime);
  console.log(task);
  console.log(notes);
  const token = localStorage.getItem("token");
  const settings = {
    url: "http://localhost:8080/tasks",
    type: "POST",
    dataType: "json",
    data: data,
    contentType: "application/json, charset=utf-8",
    headers: {
      Authorization: `Bearer ${token}`
    },
    success: function() {
      console.log("Now we are cooking with gas");
    },
    error: function(err) {
      console.log(err);
    }
  };
  $.ajax(settings);
}

handleTaskSubmit();
JavaScript 节点:.js AJAX Express 客户端

评论

0赞 jtate 2/8/2019
尝试删除 和 JUST 直接传入数据对象。JSON.stringify
0赞 Jack Surtees 2/8/2019
我以前试过,但无济于事:(
0赞 jtate 2/8/2019
您是否将浏览器控制台中的请求与 Postman 请求进行了比较?是否有任何不同的标题或正文不同?
0赞 Jack Surtees 2/8/2019
它们都是相同的:正文完全相同,并且标头中都有一个 Bearer 令牌
0赞 jtate 2/8/2019
如果它们确实相同,那么您的服务器也应该将它们视为相同。这两个请求之间必须有一些不同之处。

答:

2赞 Ivan Kolyhalov 2/8/2019 #1

我会做什么:

  1. 将标头“application/json”更改为“application/x-www-form-urlencoded”,因为官方文档没有关于前者的信息。
  1. 停止使用 $.ajax 并熟悉 XHR 请求,因为当 CDN 滞后并且 XHR 是本机实现并立即可用时,来自 CDN 的 jquery 有时会一团糟。是的,这是一个代码混乱,但你总是知道这不是内部库逻辑的事情,而是你自己的问题。你盲目地使用库,它把XHR隐藏在里面,你不知道如何问正确的问题“XHR后方法文档”,因为你还不熟悉下面的基本技术。

保存此内容并导入变量

var httpClient = {

        get: function( url, data, callback ) {
            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function () {
                var readyState = xhr.readyState;

                if (readyState == 4) {
                    callback(xhr);
                }
            };

            var queryString = '';
            if (typeof data === 'object') {
                for (var propertyName in data) {
                    queryString += (queryString.length === 0 ? '' : '&') + propertyName + '=' + encodeURIComponent(data[propertyName]);
                }
            }

            if (queryString.length !== 0) {
                url += (url.indexOf('?') === -1 ? '?' : '&') + queryString;
            }

            xhr.open('GET', url, true);
            xhr.withCredentials = true;
            xhr.send(null);
        },

        post: function(url, data, callback ) {
            var xhr = new XMLHttpRequest();

            xhr.onreadystatechange = function () {
                var readyState = xhr.readyState;

                if (readyState == 4) {
                    callback(xhr);
                }
            };

            var queryString='';
            if (typeof data === 'object') {
                for (var propertyName in data) {
                    queryString += (queryString.length === 0 ? '' : '&') + propertyName + '=' + encodeURIComponent(data[propertyName]);
                }
            } else {
                queryString=data
            }

            xhr.open('POST', url, true);
            xhr.withCredentials = true;
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.send(queryString);
        }
    };

用法就像jquery一样简单: httpClient.post(Url, data, (xhr) => {})

  1. 检查是否在 app.js 中设置了正文解析器

    var bodyParser = require('body-parser'); app.use(bodyParser.json()); // get information from html forms app.use(bodyParser.urlencoded({ extended: true })); // get information from html forms

  2. 如果设置了正文解析器,请尝试将标头更改为“multipart/form-data”或 '文本/纯文本'。

  3. 只是为了检查 req.query

评论

0赞 Jack Surtees 2/8/2019
感谢伊万向我展示了引擎盖下发生的事情!我尝试了你的解决方案;但是,我的请求正文仍记录为空对象:(