2017-04-14 72 views
0

所以,下面是我的server.js文件中的代碼片段。運行時,我發送帶有消息的URL,res.end()會使視圖呈現空白頁面。在節點服務器中使用res.end()時遇到問題

當我註釋掉res.end()命令時,視圖會顯示所有消息,但瀏覽器會等待並等待來自服務器的響應已完成的信號。

我得到,你可以使用res.end()並把數據放在parens,由視圖傳輸和呈現。

我希望發生的事情是,沒有參數,它只會離開視圖,但是參數中的空參數顯示爲空視圖。

如何在不刪除視圖上的數據的情況下指出響應已完成?

server.js

var http = require('http'), 
     url = require('url'), 
     fs = require('fs'); 

var messages = ["testing"]; 
var clients = []; 

http.createServer(function(req,res) { 
    var url_parts = url.parse(req.url); 
    console.log(url_parts); 
    if(url_parts.pathname == '/') { 
     // file serving 
     fs.readFile('./index.html', function(err, data) { 
     // console.log(data); 
     res.end(data); 
     }); 
    } else if(url_parts.pathname.substr(0,5) == '/poll'){ 
    //polling code 
    var count = url_parts.pathname.replace(/[^0-9]*/,''); 
    console.log(count); 
    if(messages.length > count){ 
     res.end(JSON.stringify({ 
     count: messages.length, 
     append: messages.slice(count).join("\n")+"\n" 
     })); 
    } else { 
     clients.push(res); 
    } 
    } else if(url_parts.pathname.substr(0, 5) == '/msg/') { 
    // message receiving 
    var msg = unescape(url_parts.pathname.substr(5)); 
    messages.push(msg); 
    while(clients.length > 0) { 
    var client = clients.pop(); 
    client.end(JSON.stringify({ 
     count: messages.length, 
     append: msg+"\n" 
    })); 
    } 
    // res.end(); //if left in, this renders an empty page, if removed, 
    // client keeps waiting.... 
    } 
    }).listen(8080, 'localhost'); 
    console.log('server running!'); 

的index.html

<html> 
<head> 
    <script src="http://code.jquery.com/jquery-1.6.4.min.js"></script> 
    <script> 
    var counter = 0; 
    var poll = function() { 
     $.getJSON('/poll/'+counter, function(response) { 
     counter = response.count; 
     var elem = $('#output'); 
     elem.text(elem.text() + response.append); 
     //elem.text(counter); 
     poll(); 
     }); 
    } 
    poll(); 
    </script> 
</head> 
<body> 
    <textarea id="output" style="width: 90%; height: 90%;"> 
    </textarea> 
</body> 
</html> 

我看過的文檔,但我沒有看到具體的關於使用.END()方法用空參數傳遞給什麼表示並結束而不傳遞要呈現的數據。我用google搜索了這個,但我還沒有答案。

+0

你能發佈完整的工作代碼嗎? –

+0

'當我註釋掉res.end()命令時,視圖顯示所有消息',你是怎麼做到的?你的代碼沒有顯示任何'client.end()' – shaochuancs

+0

@ abhyudit-jain的邏輯,server.js文件的完整工作代碼現已發佈在上面,在此先感謝您的想法 –

回答

0

改爲執行res.json({success:「true」})。原因是因爲res.end固有地認爲客戶端在流關閉之前發送了一個視圖。使用res.json(),您可以發送任何通用數據,而不需要預期的隱含視圖,也可以關閉客戶端和服務器端的流。

+0

我得到了以下錯誤:TypeError:res.json不是一個函數。那是因爲.JSON是一個快速函數,而不是一個節點函數?我不需要在這個應用程序快遞(至少還沒有),只是http –

0

移動res.end()while

while (clients.length > 0) { 
    var client = clients.pop(); 
    client.end(JSON.stringify({ 
     count : messages.length, 
     append : msg + "\n" 
    })); 
    if(!clients.length) { 
     res.end(); 
    } 
} 
+0

我試過這個,與上面的代碼相同的問題,例如,當我打電話給/味精/消息,我可以說它已發佈,但隨後將其刪除,大概是通過空的.end()命令。謝謝你的幫助。任何其他想法? –

0

我理解你的問題是:

  1. 您有一個HTML頁面(index.html),其中有一個textarea顯示提交的用戶的所有郵件。收到並顯示一條消息後,它將立即發送下一條消息的請求(/poll/<n>)。
  2. 要接受用戶輸入的最新消息,請打開一個API(/msg/<message>)。當向該API發送HTTP請求時,服務器將提取該消息,並將此消息返回到步驟1中發送的/poll/<n>
  3. 但是,由於HTML頁面(index.html)和/msg/<message>的請求發生在同一個瀏覽器窗口中,您不能讓node.js中的/msg/<message>的http處理程序調用res.end(),因爲在這種情況下,瀏覽器窗口將呈現請求(空白頁)的HTTP響應/msg/<message>。實際上,無論返回的數據如何,您都無法使res返回200 OK。你不能讓res請求/msg/<message>請求(使用req.destroy()),因爲在這種情況下,瀏覽器窗口將呈現失敗/損壞的頁面,這更糟糕。
  4. 不幸的是,您無法在node.js中使的res保持掛起狀態。雖然它會更新index.html,但瀏覽器窗口將一直等待...

你的問題的根本原因是:瀏覽器窗口資源衝突index.html之間/msg/<message>響應 - 只要/msg/<message>請求是通過用index.html窗口的地址欄,當它發回響應,窗口內容(發送index.html)將被清理。

一個解決方案是:使用Ajax發送/msg/<message>。這樣,窗口資源就不會發生衝突。示例代碼列出如下:

<body> 
    <textarea id="output" style="width: 90%; height: 90%;"> 
    </textarea> 
    <div> 
    <input type="text" id="msg"> 
    <button type="button" onclick="submitMsg()">Submit</button> 
    </div> 
</body> 

window.submitMsg = function() { 
    var msg = $('#msg').val(); 
    $.getJSON('/msg/' + msg, function(res) { 
    $('#msg').val(''); 
    console.log('message sent.'); 
    }); 
} 

編輯: 另一個較簡單的解決方法是:在一個瀏覽器窗口中打開index.html,並在另一個(使用res.end('message received successfully'),以指示消息接收結果)開放/msg/<message>

+0

我將不得不在家看看這個。看起來很合理。我知道,當我打開多個瀏覽器,然後從一個瀏覽器發送消息,其他瀏覽器正確更新,這很好,但我發送的瀏覽器被擦乾淨。 –

+1

@CaptainChaos是你的問題解決?如果是的話,也許你可以「接受」其中的一個答案? – shaochuancs

+0

我忙於其他事情。我還沒有找到答案,但還沒有嘗試過所有建議。我會在一週左右回到這個。感謝您的耐心,並提醒 –

相關問題