Как я могу обнаружить нулевые данные JSON, отправленные на мою конечную точку HTTP REST http?Это нарушает мой серверный код - PullRequest
1 голос
/ 08 мая 2019

Я создал конечную точку REST для получения данных JSON через HTTP-сообщение, через XMLHttpRequest в качестве моего клиента.Работает нормально.Однако я хотел проверить, не отправляет ли мой клиент вообще никаких данных, то есть ноль, так что мой сервер будет корректно обрабатывать это.За исключением ... он сбивает сервер с синтаксической ошибкой, когда я пытаюсь выполнить простой тест по запросу, или даже просто вывести его с помощью console.log.Я не могу понять, как проверить на нулевое условие.

Сервер Express (v 4.16.4) под node.js (v 11.4.0).

я получаю ошибку:

SyntaxError: Unexpected token n in JSON at position 0

Я много гуглил для этого, но очень мало удачи с токеном 'n'.

Я пытался: Тестирование существования req с

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);
    ....

Правильная работа с данными = {"stack": "overflow"}:

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

Ошибка при отправке данных = 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)
    ....

Спасибо за любую помощь

[ОБНОВЛЕНИЕ: Предоставление примеров кода, чтобы помочь воспроизвести эror]

Я не был уверен, было ли это уместно, но я собираю, используя babel.Вот четыре примера кода:

  • package.json
  • client.js
  • server.js
  • .babelrc

Я встраиваю в корневой каталог (после установки npm) с помощью npm run-script build Я запускаю сервер с npm start Я запускаю клиент с простым узлом 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"
  }
}

Server.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...

});

Client.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"]
}

Спасибо закомментарии и предложения, очень ценятся.

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

[решено] [bendataclear] 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
}));

Ответы [ 2 ]

1 голос
/ 08 мая 2019

Эта ошибка генерируется 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
}));

edit более чистым способом:

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
}));
0 голосов
/ 08 мая 2019

Похоже, проблема связана с вашим состоянием:

Я пытался: проверить наличие req с помощью if(req){ ... }

Я думаю, что изменив его на

if(req.body){
   //handle it here
}

может решить вашу проблему.Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...