简体   繁体   English

NodeJS异步.end()不适用于POST请求

[英]NodeJS asynchronous.end() not working on POST request

I am trying to return text based on database query - for account registration - on the $.ajax success' parameter, after many search, I can't get what is wrong with the code below. 我试图返回基于数据库查询的文本-​​用于帐户注册-在$ .ajax success'参数上,经过多次搜索,我无法理解下面的代码出了什么问题。

I can't find how to send http response that require asynchronous function, if I try to do it, the request is not handled or detected at all. 我找不到如何发送需要异步功能的http响应,如果尝试这样做,根本不会处理或检测到该请求。

I think that the problem is that my that res.end("false") call is not called in time, but the code looks correct to me. 我认为问题在于我的res.end(“ false”)调用未及时调用,但代码对我来说似乎正确。

I don't want to use express and all callback are working correctly however I'm sure the problem is on server.js where I put comment 我不想使用express并且所有回调都正常工作,但是我确定问题出在我放置评论的server.js

client-side: 客户端:

$.ajax({
     async: true,
     dataType: "text",
     type: 'POST',
     url: 'http://192.168.0.23:3000',
     data: JSON.stringify(account_info),
     contentType: 'application/json; charset=utf-8',
     success: function (res) {
         console.log('Account registration : ' + res);
     },
     complete: function (res) {
            console.log('Account registration complete : ' +  
            JSON.stringify(res));
     },
    error: function (err) {
        console.log(err.responseText)
    }
});

server-side: 服务器端:

server.js server.js

const http = require('http');
var mongoose = require('mongoose');
var Visitor = require('./models/visitor.js');
var Account = require('./models/account.js');
var api = require('./controllers/api.js');
var isExisting = api.isExisting;
var saveData = api.saveData;
const port = 3000;

const server = http.createServer();
console.log('server is listening on ' + port);
server.listen(port);
server.on('request', function (request, response) {

    response.setHeader('Access-Control-Allow-Origin', '*');
    response.setHeader('Access-Control-Allow-Methods', 'POST');
    response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    console.log(request.method);

    var body = '';

    request.on('data', function (data) {
        body += data;
    });

    request.on('end', function () {

        //In case there's content in the POST request
        if (body) {
            console.log('\nRequest content:' + body + '\n');
            body = JSON.parse(body);
            mongoose.Promise = global.Promise;
            mongoose.connect('mongodb://localhost/someDB', {
                useMongoClient: true
            });

            //Pattern = ACCOUNT_REGISTRATION
            if (body.pattern == 'account_registration') {
                var value = {
                    email: body.email
                }
                var new_data = new Account(Account.store(body));
                //Check if account_name or website URL already in db
                // exist returning the callback
                isExisting(Account, value, function (exist) {
                    console.log(exist);
                    if (!exist) {
                        saveData(new_data);
                        //If you dont remove this line, the request is not detected by nodeJS
                        response.end('true');

                    } else {
                        console.log('\nAccount already exist.');
                        //If you dont remove this line, the request is not detected by nodeJS
                        response.end('false');
                        mongoose.connection.close();

                        }

                    });
                }
            }
            //Here it's working good but If I remove this line it'll not handle the request at all
            response.end('oko');
        });
    });

api.js api.js

// The API controller
var mongoose = require('mongoose');

//Send some new_data to db
exports.saveData = function (new_data) {
    //Data saving into MongoDB database
    new_data.save(function (err) {
        if (err) {
            throw err;
        }
        console.log('\nData successfully added.');
        // We need to disconnect now
        mongoose.connection.close();
    });
}

exports.isExisting = function (ModelName, value, callback) {
    ModelName.count(value, function (err, count) {
        if (err)
            throw err;
        if (count == 0)
            callback(false);
        else
            callback(true);
    });
}

LAST EDIT: In short, 最后编辑:总而言之,

This is what I get when I don't remove the last line (normal behavior but I can't get my asynchronous response 这是我不删除最后一行时得到的结果(正常行为,但我无法获得异步响应

server is listening on 3000 
OPTIONS 
POST Request content:{"*****"}//real data already in db 
true //This is isExisting() callback
Account already exist. 

But when I remove the last response.end('oko'), everything after OPTIONS not appear... 但是当我删除最后一个response.end('oko')时,OPTIONS之后的所有内容都不会出现...

I understand the issue now. 我现在了解这个问题。

You're making a CORS request. 您正在提出CORS要求。 And all CORS requests send an OPTIONS request first to the server before sending the actual request to check if the Access Control headers actually allow the request to be handled by the server. 并且所有CORS请求都先向服务器发送OPTIONS请求,然后再发送实际请求,以检查访问控制标头是否实际上允许服务器处理该请求。

Since your request handler checks for the existance of a body.pattern, which won't exists for a OPTIONS request, the response is never sent. 由于您的请求处理程序会检查body.pattern的存在(对于OPTIONS请求而言将不存在),因此永远不会发送响应。

So the request never gets responded to and your POST request never reaches the server because it doesn't get permission to do so from the OPTIONS request. 因此,该请求永远不会得到响应,并且您的POST请求也永远不会到达服务器,因为它没有获得OPTIONS请求的许可。

So if you add something like if ( method === 'OPTIONS' ) { response.end() } else if ( body ) { ... } you'll assure that the options will get handled. 因此,如果您添加类似if ( method === 'OPTIONS' ) { response.end() } else if ( body ) { ... }您将确保可以处理这些选项。

To be safe make sure that all requests get answered, even if you just answer with an error or a 404. 为了安全起见,即使您只是回答有错误或404,也请确保所有请求都得到答复。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM