Пустое тело запроса Node js с CORS и JSON

Я публикую эту тему по проблеме, предложенной в заголовке. Я видел несколько других вопросов, касающихся пустых тел запросов, но ни один из них мне не помог. Надеюсь, если я опубликую свой собственный код, кто-то сможет дать мне хороший совет.

В основном у меня есть клиент, использующий javascript для отправки CORS HTTPRequests на сервер Node.js. Обычно эти HTTPRequests представляют собой записи объектов JSON.

Вот пример кода клиента.

username = document.getElementById("username").value;
password = document.getElementById("password").value;
var str = '{"name":"'+username+'","pass":"'+password+'"}';
var req = new XMLHttpRequest();
req.open("POST","http://xxxx:8099/register",true)
req.setRequestHeader("Content-type", "application/json");
req.onreadystatechange = function() 
{
     //irrelevant
}
req.send(str);

}

Вот код сервера.

var express    = require('express');
var bodyParser = require('body-parser');
var app = express();
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({
extended: true
}));

// parse application/json
app.use(bodyParser.json());
app.listen(8099);
app.post("/register", function (req, res) {
console.log(req.body); // populated!
console.log(req.body.name);
res.send(200, req.body);
});

Теперь вот результаты, которые я получаю:

Если я устанавливаю Content-type запроса в application/json, то на сервере я получаю пустое тело запроса.

Если я установлю для Content-type запроса значение application/x-www-form-urlencoded, то получу заполненное тело, например { '{"name":"usernamtest","pass":"123"}': ' ' }.

Однако, если я попытаюсь напечатать req.body.name, я получу неопределенное значение, что означает, что синтаксический анализатор тела неправильно проанализировал тело в JSON.

Как я решу это? Я просто хочу получить объект JSON этих свойств в примере.

Для тех, кто читает это, я благодарю вас за ваше время. Дополнения, Рикардо Феррейра да Силва


person Ricardo Ferreira da Silva    schedule 30.12.2015    source источник
comment
Вы уверены, что код не работает? Попробовал сам, и я получил ожидаемые результаты (имя напечатано на консоли). Правильно ли вы получаете данные из входных данных? Вы можете попробовать очистить код XHR: jsbin.com/revovemepu/edit?js   -  person adrianp    schedule 30.12.2015
comment
Да, я уверен, на самом деле клиент отлично работает с тестовым сервером, который уже сделал мой профессор, просто он не работает с моим. Если я запускаю код как есть, когда я печатаю req.body, я получаю {}, что является пустым телом.   -  person Ricardo Ferreira da Silva    schedule 30.12.2015
comment
Что такое xxxx в xxxx:8099/register? Вы действительно делаете междоменный запрос? Отличается ли домен, из которого вы обслуживаете HTML-страницу, в которую встроен ваш клиентский JS, от домена, на котором вы делаете XHR?   -  person adrianp    schedule 30.12.2015
comment
Полный адрес: twserver.alunos.dcc.fc.up.pt:8099/. зарегистрируйтесь, это сервер Apache, созданный для того, чтобы я мог разместить свой сервер node.js. Это может быть важно, я обнаружил, что когда я пытаюсь отправить строковый JSON в запросе, я получаю следующую ошибку: XMLHttpRequest не может загрузить twserver.alunos.dcc.fc.up.pt:8099/register. Ответ на предварительный запрос не проходит проверку управления доступом: в запрошенном ресурсе отсутствует заголовок «Access-Control-Allow-Origin». Таким образом, Origin 'null' не имеет доступа.   -  person Ricardo Ferreira da Silva    schedule 30.12.2015
comment
А файл index.html откуда подается?   -  person adrianp    schedule 30.12.2015
comment
См. github.com/expressjs/cors.   -  person adrianp    schedule 30.12.2015
comment
comment
Я запускаю клиент (с index.html) локально, он нигде не размещен, только на сервере.   -  person Ricardo Ferreira da Silva    schedule 30.12.2015
comment
Это твоя проблема; обслуживайте файл index.html с того же сервера, на котором у вас есть маршрут регистрации, см.: expressjs.com/en/starter/static-files.html   -  person adrianp    schedule 30.12.2015
comment
Да, я только что прочитал об этом! Однако я думаю, что мог решить проблему, добавив эту строку. Разрешает ли он несколько маршрутов? app.use(function(req, res, next) { res.header(Access-Control-Allow-Origin, *); res.header(Access-Control-Allow-Headers, Origin, X-Requested-With, Content- Тип, Принять); следующий(); });   -  person Ricardo Ferreira da Silva    schedule 30.12.2015
comment
Да, это будет работать для любого количества добавленных вами маршрутов.   -  person adrianp    schedule 30.12.2015


Ответы (1)


В современный веб-браузер добавлено новое требование безопасности, которое помогает предотвратить несанкционированный доступ к вашему веб-сервису из другого домена. Взлом CSRF (или подделка межсайтовых запросов) включает в себя выполнение HTTP-запросов из другого домена к веб-службе в попытке нарушить безопасность сервера и получить доступ к потенциально ценным данным, хранящимся на сервере. Если браузер видит, что запрос направляется в тот же домен, что и веб-сайт, с которого сделан запрос, он разрешает выполнение запроса. Если же домены разные и запрос включает в себя что-то иное, чем получение статического файла, браузер сначала проверяет наличие разрешения на доступ к сервису с сервера.

Заголовки CORS (или совместное использование ресурсов между источниками) — это то, на что сервер должен ответить, чтобы уведомить браузер о том, что разрешено. CORS может вносить в белый список домены, методы http и определенные заголовки.

Этот процесс известен как предварительная проверка CORS.

Используя следующий заголовок:

Доступ-Контроль-Разрешить-Происхождение: *

По сути делает так, что все домены имеют доступ. Веб-сервис является полностью общедоступным. Это может оставить зияющую дыру в безопасности, если вы не хотите, чтобы ваш сервис был общедоступным.

Access-Control-Request-Method указывает, какие методы HTTP разрешены. Запросы GET часто разрешены по умолчанию, если это разрешено.

Access-Control-Request-Age определяет, как долго будет работать предварительная проверка CORS. Это измеряется в секундах.

Access-Control-Allow-Headers указывает любые заголовки, которые принимаются сервером.

Я настоятельно рекомендую узнать о взломе AJAX и способах его предотвращения (если вы еще этого не сделали).

person Timothy    schedule 30.12.2015