Express Node.js ответ на AJAX звонок от клиента не отправляется полностью - PullRequest
0 голосов
/ 14 апреля 2020

я использую запрос ajax get для получения данных с сервера (структура списка воспроизведения spotify, которая будет отображаться для пользователя. Но у меня возникли некоторые проблемы с передачей. Эта проблема встречается только при использовании внешнего ip (а не с localhost)

Данные, принимаемые правильно на localhost: enter image description here

с заголовками:

Request URL: http://www.localhost:8080/spotify/ajax/requestSongs
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
Content-Length: 821946
Content-Type: application/json; charset=utf-8
Date: Tue, 14 Apr 2020 19:18:51 GMT
ETag: W/"c8aba-7NdUbhReuN0XXnw3DPVSyrNAS38"
X-Powered-By: Express
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Cookie: connect.sid=s%3A0yZXFKy7MgsfbY_OX5yanp5HKlvdSGKY.8BaJrUmEGn9z9ohyRTtkXBCTj6wxiDDoaLNFS8vEdl8
Host: www.localhost:8080
If-None-Match: W/"c8aba-7NdUbhReuN0XXnw3DPVSyrNAS38"
Referer: http://www.localhost:8080/spotify/edit?playlist=5LDRNl7lGrxm7mx2RVggVC
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36

Данные являются неправильно получен на внешний ip: timing file

с заголовками:

Request URL: http://86.90.233.152:8080/spotify/ajax/requestSongs
Request Method: GET
Status Code: 200 OK
Remote Address: MYIP:8080
Referrer Policy: no-referrer-when-downgrade
Connection: keep-alive
Content-Length: 821946
Content-Type: application/json; charset=utf-8
Date: Tue, 14 Apr 2020 19:03:00 GMT
ETag: W/"c8aba-7NdUbhReuN0XXnw3DPVSyrNAS38"
X-Powered-By: Express
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: nl-NL,nl;q=0.9,en-US;q=0.8,en;q=0.7
Connection: keep-alive
Cookie: connect.sid=s%3AlGbD5iWpq9sJlLCFvBsj20RkR9_gZrEr.D9rOpXr5M6FfHnUe7DUx0xzLybQhsGsLIuYsys0FrP4
Host: 86.90.233.152:8080
Referer: http://MYIP:8080/spotify/edit?playlist=5LDRNl7lGrxm7mx2RVggVC
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36

Ответ ajax не изменяется после второго ответа XMLhttp. Кроме того, чтобы попытаться найти проблему, я регистрирую каждый ответ, приходящий на ajax, и консоль:

clientscript.js:8 XMLHttpRequest {readyState: 1, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
clientscript.js:8 XMLHttpRequest {readyState: 2, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
clientscript.js:8 XMLHttpRequest {readyState: 3, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
clientscript.js:8 XMLHttpRequest {readyState: 3, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}

ИСТОЧНИК:

Ответчик на стороне сервера

router.get("/ajax/requestSongs", function(req,res, next)
{
  if(req.session.lastPlaylist)
  {
    localPlaylists[res.locals.sessionId].getSortedGenres((sortedGenres) => localPlaylists[res.locals.sessionId].getPlaylist( (playlist) => 
    {
      var data={sortedGenres : sortedGenres, playlist : playlist}
      console.log(data);
      res.send(data);
    }));
  }

});

Клиент боковой приемник:

function getData(suburl, callback)
{
    var xhttp = new XMLHttpRequest();
    xhttp.onreadystatechange = function() {
        //console.log(this.responseText);
        console.log(this)
        if (this.readyState == 4 && this.status == 200) 
        {
            console.log(this.responseText);
            callback(this.responseText);
        }
    };
    xhttp.open("GET", pathPrefix+"/ajax/"+suburl, true);

    xhttp.send();
}

Пример того, как данные обрезаются (правильные данные .......):

........"art rock","blues rock","classic rock","hard rock","metal","psychedelic rock","rock","soft rock"]},{"artists":[{"external_urls":{"spotify":"https://open.s

1 Ответ

0 голосов
/ 15 апреля 2020

Поскольку это имеет значение только тогда, когда вы находитесь на внешней ссылке, и данные большие (не огромные, но и не маленькие), я подозреваю, что есть какая-то проблема с передачей, возможно, какой-то внутренний буфер проблема переполнения. У меня сложилось впечатление, что res.send() должен просто «обрабатывать это для вас», но, очевидно, это не так.

Сначала я бы добавил обработчик ошибок в выходной поток и посмотрел, регистрируется ли он что-нибудь:

router.get("/ajax/requestSongs", function(req, res, next)
{
  if(req.session.lastPlaylist)
  {
    localPlaylists[res.locals.sessionId].getSortedGenres((sortedGenres) => localPlaylists[res.locals.sessionId].getPlaylist( (playlist) => 
    {
      var data={sortedGenres : sortedGenres, playlist : playlist}
      console.log(data);

      // log any errors on the response stream
      res.on('error', function(err) {
         console.log(err);
      });

      res.send(data);
    }));
  }

});

Тогда моя теория о некотором переполнении буфера предполагает, что вам нужно реализовать управление потоком при отправке данных. Я думал, что res.send() должен был сделать это для вас, но вы можете реализовать это сами, как это, и посмотреть, решит ли это проблему:

router.get("/ajax/requestSongs", function(req, res, next) {
    if(req.session.lastPlaylist) {
        localPlaylists[res.locals.sessionId].getSortedGenres((sortedGenres) => localPlaylists[res.locals.sessionId].getPlaylist( (playlist) => {
            res.type("application/json");
            res.status(200);

            const data = JSON.stringify({sortedGenres : sortedGenres, playlist : playlist});
            const chunkSize = 1024 * 10;   // send in 10k chunks
            let pos = 0, chunk;

            function sendNextChunk() {
                if (pos < data.length) {
                    chunk = data.substr(pos, chunkSize);
                    pos += chunkSize;
                    let flushed = res.write(chunk);
                    if (!flushed) {
                        // need to wait for drain event before sending more
                        res.once('drain', sendNextChunk);
                    } else {
                        // send more without stack build-up
                        setImmediate(sendNextChunk);
                    }
                } else {
                    // finish the response
                    res.end();
                }
            }

            // log any write errors on the response
            res.on('error', function(err) {
                console.log(err);
            });

            // start the sending sequence
            sendNextChunk();
        }));
    } else {
      // have to send something here when no playlist
        res.send("No previously established playlist");
    }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...