javascript - 如何检测发送到我的 REST http post 端点的空 JSON 数据?它破坏了我的服务器代码

标签 javascript node.js rest express

我已经创建了一个 REST 端点来通过 HTTP post 接收 JSON 数据,通过 XMLHttpRequest 作为我的客户端。它工作正常。但是我想测试我的客户端是否根本不发送任何数据,即 null,所以这将由我的服务器优雅地处理。除了...当我尝试对请求执行简单测试时,它会因语法错误而使服务器崩溃,或者甚至只是使用 console.log 来回显它。我似乎不知道如何测试 null 条件。

服务器是 Node.js (v 11.4.0) 下的 Express (v 4.16.4)。

我得到的错误是:

SyntaxError: Unexpected token n in JSON at position 0

我为此做了很多谷歌搜索,但对 token “n”的运气却很差。

我试过: 用

测试请求是否存在
if (req) {
    ...

try {
    console.log(req);
} 
catch(err) {
    console.log("Caught error: "+err);
}

甚至是一个很好的老人:

router.route('/api/endpoint/:filename').post((req, res, err) => {
    if (err) {
        console.log("Caught error: "+err);
    } else {
        ...

这有点令人担忧,因为虽然我可以控制从我的客户端发送到端点的内容,而且我知道发送空负载没有意义并且是无效的,但是如果其他人(恶意地?)将空负载发送到API,并轻而易举地破坏了服务器?

为了完整起见,这是我的客户端代码和服务器函数。

客户:

// Testing sending null data to a REST endpoint
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
var url = "http://localhost:4001/api/endpoint/delme.txt";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var json = JSON.parse(xhr.responseText);
        console.log(json.email + ", " + json.password);
    }
};

data = null;        // Normally I'd send a JSON object
                    // e.g. data = {"stack" : "overflow"}
// data = {"stack" : "overflow"};
xhr.send(JSON.stringify(data));

服务器函数:

router.route('/api/endpoint/:filename').post((req, res) => {
    if (req)
        console.log("Got req");
    else    
        console.log("nothing...");

    console.log("Body....");
    console.log(req.body);
    ....

正确使用 data = {"stack": "overflow"}:

Got req
Body....
{ stack: 'overflow' }

当我发送 data = null 时出错:

SyntaxError: Unexpected token n in JSON at position 0
    at JSON.parse (<anonymous>)
    at createStrictSyntaxError (C:\Users\roryc\source\repos\ang09server\node_modules\body-parser\lib\types\json.js:158:10)
    ....

感谢您的帮助

[更新:提供代码示例以帮助重现错误]

我不确定它是否相关,但我正在使用 babel 进行编译。以下是四个代码示例:

  • package.json
  • 客户端.js
  • server.js
  • .babelrc

我使用 npm run-script build 在根目录中构建(在 npm 安装之后) 我用 npm start 执行服务器 我用一个简单的 Node dist/client.js 执行客户端

Package.json:

{
  "name": "server",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "nodemon --exec babel-node src/server.js",
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "babel-watch src/server.js",
    "build": "babel src --out-dir dist",
    "serve": "node dist/server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.4",
    "xmlhttprequest": "^1.8.0"
  },
  "devDependencies": {
    "@babel/cli": "^7.4.4",
    "@babel/core": "^7.4.4",
    "@babel/node": "^7.2.2",
    "@babel/preset-env": "^7.4.4",
    "nodemon": "^1.19.0"
  }
}

服务器.js:

import express from 'express';
import bodyParser from 'body-parser';

const app = express();
const router = express.Router();
const http = require('http').Server(app);

app.use(bodyParser.json());
app.use('/', router);

http.listen(4001, function() {
    console.log('Express listening (+web sockets) on port 4001');
});

router.route('/api/endpoint/:filename').post((req, res) => {
    console.log(req.body);  // Error appears here...

    // Function logic goes here...

});

客户端.js:

// Testing sending null data to a REST endpoint
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
var url = "http://localhost:4001/api/endpoint/delme.txt";
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
    if (xhr.readyState === 4 && xhr.status === 200) {
        var json = JSON.parse(xhr.responseText);
        console.log(json.email + ", " + json.password);
    }
};

var data = null;        // Normally I'd send a JSON object, e.g. data = {"stack" : "overflow"}
// var data = [{"stack" : "overflow"}];
xhr.send(JSON.stringify(data));

.babelrc:

// .babelrc
{
    "presets": ["@babel/preset-env"]
}

感谢您的意见和建议,非常感谢。

......................

[已解决] [本数据清除] 1提供了答案和(几乎)工作代码,我对其进行了非常小的调整,现在可以正确捕获正在发送的空数据并抛出错误而服务器不会出现故障。在此处重现解决方案,以防对其他人有所帮助。非常感谢 bendataclear。

// Verification function for bodyparser to test for null data being sent
const vfy = (req, res, buf, encoding) => {
    console.log("Received buffer: "+buf);
    if (buf.equals(Buffer.from([0x6e, 0x75, 0x6c, 0x6c]))){ // Check for characters 'null' in buffer
        throw new Error('null body');
    }
};

app.use(bodyParser.json({
    verify: vfy
}));

最佳答案

这个错误是由 bodyparser 抛出的,因此在你的路由之前被命中。

您可以通过为 bodyparser 禁用严格模式来停止此错误:

app.use(bodyParser.json({
    strict: false
}));

然而,这可能不是最佳选择,另一种捕获此错误的方法是为 bodyparser 提供一个验证选项,然后这可以抛出一个更有意义的错误(可能有更简洁的方法来执行此操作):

const vfy = (req, res, buf, encoding) => {
    if (buf.length === 4 && buf[0] === 110 && buf[1] === 117 
                         && buf[2] === 108 && buf[3] === 108){ // Check for characters 'null' in buffer
        throw new Error('null body');
    }
};

app.use(bodyParser.json({
    verify: vfy
}));

编辑更简洁的方式:

const vfy = (req, res, buf, encoding) => {
    if (buf.equal(Buffer.from(110,117,108,108))){ // Check for characters 'null' in buffer
        throw new Error('null body');
    }
};

app.use(bodyParser.json({
    verify: vfy
}));

关于javascript - 如何检测发送到我的 REST http post 端点的空 JSON 数据?它破坏了我的服务器代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56033559/

相关文章:

javascript - jQuery 空输入检查功能未按预期工作

javascript - React Native,如何将嵌套的if else转换为switch语句?

javascript - Node : Using fs. readFile 读取错误 : EISDIR: illegal operation on a directory,

ajax - Redis 成员与 Node

node.js - AWS Lambda : How to store secret to external API?

javascript - 如何使查询 WebSQL 不减?

Android 客户端和 PHP 服务器 : common practice in communication

rest - Rest api 中的事件流是什么以及为什么我们需要它?

javascript - 我应该通过 Node 应用程序中的 Restful api 进行所有数据库调用吗?

javascript - 对多种表单使用一个 JavaScript 函数