我會使用你提供的代碼,並提供一個答案比什麼是覆蓋在你的問題,以適應人在遙遠的未來更徹底。我還會提供一個使用「Vanilla JS」(http://www.vanilla-js.com/)的答案,因爲我想太多時髦人士在嘗試學習這種方法時會說「使用框架」。我認爲他們這樣做的原因是因爲有人告訴他們在學習如何工作時「使用框架」。因爲他們不是黑客,他們並不在意嘗試和理解這個過程,所以很多時候他們不知道如何獨立完成這個工作,沒有框架(因此無處不在「使用框架」)。通過了解發生了什麼,你會成爲一個更好的黑客,我希望這個答案能幫助你。
既然您希望通過您輸出的表單接受POST(表單)數據,則需要在您的服務器中提供路由機制。這意味着您會告訴您的服務器將表單提供給訪問您網站的人員,但如果用戶提交表單,Node會將POST數據路由到一個小處理函數。我已經提供了完整的答案,然後將其進一步剖析,以適應想要從代碼學習的人。
var http = require('http');
var qs = require('querystring');
var formOutput = '<html><body>'
+ '<h1>XYZ Repository Commit Monitor</h1>'
+ '<form method="post" action="inbound" enctype="application/x-www-form-urlencoded"><fieldset>'
+ '<div><label for="UserName">User Name:</label><input type="text" id="UserName" name="UserName" /></div>'
+ '<div><label for="Repository">Repository:</label><input type="text" id="Repository" name="Repository" /></div>'
+ '<div><label for="Branch">Branch:</label><input type="text" id="Branch" name="Branch" value="master" /></div>'
+ '<div><input id="ListCommits" type="submit" value="List Commits" /></div></fieldset></form></body></html>';
var serverPort = 8124;
http.createServer(function (request, response) {
if(request.method === "GET") {
if (request.url === "/favicon.ico") {
response.writeHead(404, {'Content-Type': 'text/html'});
response.write('<!doctype html><html><head><title>404</title></head><body>404: Resource Not Found</body></html>');
response.end();
} else {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(formOutput);
}
} else if(request.method === "POST") {
if (request.url === "/inbound") {
var requestBody = '';
request.on('data', function(data) {
requestBody += data;
if(requestBody.length > 1e7) {
response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
}
});
request.on('end', function() {
var formData = qs.parse(requestBody);
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('<!doctype html><html><head><title>response</title></head><body>');
response.write('Thanks for the data!<br />User Name: '+formData.UserName);
response.write('<br />Repository Name: '+formData.Repository);
response.write('<br />Branch: '+formData.Branch);
response.end('</body></html>');
});
} else {
response.writeHead(404, 'Resource Not Found', {'Content-Type': 'text/html'});
response.end('<!doctype html><html><head><title>404</title></head><body>404: Resource Not Found</body></html>');
}
} else {
response.writeHead(405, 'Method Not Supported', {'Content-Type': 'text/html'});
return response.end('<!doctype html><html><head><title>405</title></head><body>405: Method Not Supported</body></html>');
}
}).listen(serverPort);
console.log('Server running at localhost:'+serverPort);
而現在的故障解釋了爲什麼我做了我做的事情。
var http = require('http');
var qs = require('querystring');
首先,您將添加Node的內置'querystring'模塊來解析實際的表單數據。
var formOutput = '<html><body>'
+ '<h1>XYZ Repository Commit Monitor</h1>'
+ '<form method="post" action="/inbound" enctype="application/x-www-form-urlencoded"><fieldset>'
+ '<div><label for="UserName">User Name:</label><input type="text" id="UserName" name="UserName" /></div>'
+ '<div><label for="Repository">Repository:</label><input type="text" id="Repository" name="Repository" /></div>'
+ '<div><label for="Branch">Branch:</label><input type="text" id="Branch" name="Branch" value="master" /></div>'
+ '<div><input id="ListCommits" type="submit" value="List Commits" /></div></fieldset></form></body></html>';
var serverPort = 8124;
我搬到形式輸出了我們上面的服務器/路由/表格處理機制,因爲邏輯是那麼更容易閱讀。我也將服務器端口信息移到這裏,因爲你只需要在一個地方改變它,而不是在下面。
http.createServer(function (request, response) {
(我通常會縮短這個功能,「請求」和「資源」的參數,不過這只是我的偏好。)
if(request.method === "GET") {
if (request.url === "/favicon.ico") {
response.writeHead(404, {'Content-Type': 'text/html'});
response.write(notFound);
response.end();
在這裏,我已經包括了一個簡單的路由實例。在這種情況下,我們讓我們的服務器監聽「favicon.ico」的請求 - 這是幾乎所有主要瀏覽器對網頁的所有初始請求的請求。該文件是您可以在每個訪問的網頁的標籤中看到的小圖標。對於我們的目的,我們不需要提供一個favicon,但我們會處理入站請求,以顯示一些基本的路由機制。
} else {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(formOutput);
}
如果訪問者指向他們的瀏覽器到任何其他資源使用默認的GET方法(除了「favicon.ico的」我們只是上述處理)服務器上,我們會爲他們服務的形式。
} else if(request.method === "POST") {
否則,如果您的訪問者在你的服務器指向一個帖子,它很可能他們已經提交了他們與以前的GET請求檢索的形式。
if (request.url === "/inbound") {
在這裏,我們傾聽稱爲「/入內」的入站請求 - 如果你抓住了小細節上面 - 是我們的HTML表單的「動作」。如您所知,表單的「動作」會告訴瀏覽器發送表單數據的位置。
var requestBody = '';
request.on('data', function(data) {
requestBody += data;
if(requestBody.length > 1e7) {
response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
}
});
request.on('end', function() {
var formData = qs.parse(requestBody);
這看起來有點令人困惑,但我保證它不是。 POST請求可以作爲來自客戶端瀏覽器的多部分消息發送。對於表單中幾個變量這樣小的內容,您不可能看到這一點,但隨着您處理的數據量的增加,您會看到這一點。如果您仔細觀察,您還會看到if()
聲明詢問POST數據的長度。一個惡意的人可以通過上傳一個無盡的文件來終止你的服務器,但是如果我們採取行動則不會。這會將POST數據正文限制爲大約十兆字節,但您應該相應地進行調整。瞭解這些事情可以防止未來頭痛,我不希望你頭痛。
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('<!doctype html><html><head><title>response</title></head><body>');
response.write('Thanks for the data!<br />User Name: '+formData.UserName);
response.write('<br />Repository Name: '+formData.Repository);
response.write('<br />Branch: '+formData.Branch);
response.end('</body></html>');
});
這裏是我們使用表單數據的地方。由於Javascript的本質,這些變量名稱是CASE SENSITIVE(例如「UserName」而不是「username」)。當然,你可以用這些數據做任何你想要的事情(記住Node的事件循環和異步特性)。
}
response.writeHead(404, 'Resource Not Found', {'Content-Type': 'text/html'});
return response.end('<!doctype html><html><head><title>404</title></head><body>413: Request Entity Too Large</body></html>');
繼續我們的路由實例,包括我們這裏做一個包羅萬象的下方的if()
聲明,向客戶端發送一個通用的404「未找到」回覆任何POST請求,我們還沒有準備好處理。
} else {
response.writeHead(405, 'Method Not Supported', {'Content-Type': 'text/html'});
return response.end('<!doctype html><html><head><title>405</title></head><body>405: Method Not Supported</body></html>');
}
}).listen(serverPort);
console.log('Server running at localhost:'+serverPort);
現在我們剛剛完成了代碼,包括一些代碼來處理奇怪方法的請求。有幾件事我沒有解決(功能結構,空表格數據等),但確實有很多方法可以實現您的目標。正如我的許多年前CS教授所說的,有很多方法可以編程,很容易通過分享作業看到誰在作弊。
我希望你(和其他任何人)能夠看到,使用其內置模塊而不是依賴諸如Express之類的外部第三方庫,在Node中執行某些操作並不是一些深奧或甚至稍微困難的過程。這些圖書館在世界上佔有一席之地,但不要追隨羣體:對你的代碼作出明智的決定,因爲在一天結束時,你是負責它的人(不是一些人在堆棧溢出)。
我強烈建議您使用(甚至低級別)框架來構建具有節點的應用程序。我個人使用Express(http://expressjs.com/),但如果您選擇,還有其他選項。除其他外,它將允許您輕鬆處理不同的請求類型和路由以及靜態內容。 – 2013-03-15 08:06:17
查看http://stackoverflow.com/questions/6158933/http-post-request-in-node-js – user568109 2013-03-15 11:00:12
你可以在我的博客http:// hectorcorrea上看到一個關於如何使用Express.js處理HTTP POST的簡單示例.com/blog/introduction-to-node-js – 2013-03-15 13:23:58