我試圖根據Adam Freeman的Apress「Pro JavaScript for Web Apps」中的建議設置Node。我已經在我的Mac(OS 10.6.8)的機器上安裝節點(0.10.7)並運行各種實例證明節點工作,如節點JS EACCESS錯誤(Pro JS for Web Apps書) - 路徑或權限?
var http = require('http');
http.createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}).listen(1337, '127.0.0.1');
console.log('Server running at http://127.0.0.1:1337/');
,所以我可以從終端發起節點,然後得到一個瀏覽器中的「Hello World」。目前爲止似乎都很好。
然後我發出命令,以添加本書中提出的一些套餐:
npm install node-static jqtpl
而且也適用;它通過HTTP GET命令獲得了一堆東西,似乎無錯地安裝它們。
Adam的示例文件有兩個組件:有一個「server.js」文件,每個章節都有一個包含示例的「content」目錄。我的問題似乎與文件和內容目錄之間的路徑有關,或者基於使用此EACCESS錯誤搜索一些權限問題。我嘗試了各種配置(將server.js放入我的「dave」目錄,這是我在Mac上的用戶目錄,並且將「content」目錄作爲「dave」的子目錄;這似乎是他想要的從書中的說明;或者,將server.js放入內容目錄中;由於路徑錯誤,似乎不起作用
在任何情況下,當我將「server.js」放入「dave」目錄,並讓「內容」也存在於「dave」目錄中(實際上,對於server.js駐留在目錄中的任何目錄來說都是如此,並且內容也駐留在同一目錄中),我得到以下結果:
dave$ node server.js
Ready on port 80
events.js:72
throw er; // Unhandled 'error' event
^
Error: listen EACCES
at errnoException (net.js:884:11)
at Server._listen2 (net.js:1003:19)
at listen (net.js:1044:10)
at Server.listen (net.js:1110:5)
at Object.<anonymous> (/Users/dave/NodeJsTesting/server.js:92:34)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
注意事項:我幾乎是一個Unix新手(我是一個.Net開發者),所以它可能就是我不明白Unix權限,路徑或PATH變量的原因。亞當談到把東西放在「你的Node.js目錄中」,我認爲這可能不夠具體。我對本地機器的行爲的觀察是,NODE可執行文件顯然是在我的PATH中,因爲我可以從我的用戶目錄執行上述命令。無論如何,我懷疑這是一些權限問題。
在完整性的利益,這裏是亞當的代碼:
var http = require('http');
var url = require('url');
var fs = require('fs');
var nodestatic = require('node-static');
var jqtpl = require("jqtpl");
var querystring = require('querystring');
var fileserver = new(nodestatic.Server)("./content", { cache: 1 });
var productData = JSON.parse(fs.readFileSync("./content/products.json"));
function handleRequest(req, res) {
console.log(req.method + " request for " + req.url);
if (req.method == "POST") {
var fullBody = '';
req.on('data', function(chunk) {fullBody += chunk.toString();});
req.on('end', function() {
var data = createDataObject(querystring.parse(fullBody));
if (req.headers['x-http-method-override']) {
var productID = req.url.split("/").pop();
switch (req.headers['x-http-method-override']) {
case "delete":
data.deleteItem(productID);
break;
case "put":
var item = data.getItem(productID);
if (item) {
item.name = data.getAndRemoveDataProp("name");
item.price = data.getAndRemoveDataProp("price")
}
break;
}
writeJSONData(res, productData);
} else {
switch (req.url) {
case "/formecho":
case "/basket":
case "/basket":
case "/shipping":
case "/summary":
res.write(jqtpl.tmpl(loadTemplate(req.url.substring(1)), data));
break;
}
res.end();
}
});
} else {
if (req.url.indexOf("/shortJSONP") == 0) {
var callback = querystring.parse(url.parse(req.url).query)["callback"];
res.setHeader("Content-Type", "text/javascript");
res.write(callback + "(" + JSON.stringify([productData[0]]) + ")");
res.end();
} else {
if (req.headers["origin"] && req.headers["origin"].indexOf("cheeselux") > -1) {
res.setHeader("Access-Control-Allow-Origin", req.headers["origin"]);
}
switch (req.url) {
case "/cheeselux.appcache":
fileserver.serveFile("cheeselux.appcache", 200,
{"Content-Type": "text/cache-manifest"}, req, res);
break;
case "/products.json.slow":
setTimeout(function() {
fileserver.serveFile("products.json", 200, null, req, res);
}, 1000);
break;
case "/shortJSONList":
writeJSONData(res, [productData[0]]);
break;
case "/admin/products":
writeJSONData(res, productData);
break;
default:
if (req.url == "/") {
req.url = "/example.html";
}
fileserver.serve(req, res);
break;
};
}
}
}
http.createServer(handleRequest).listen(80);
console.log("Ready on port 80");
function loadTemplate(name) {
return fs.readFileSync("content/" + name + ".html").toString();
}
function writeJSONData(res, data) {
res.setHeader("Content-Type", "application/json");
res.write(JSON.stringify(data));
res.end();
}
function createDataObject(reqData) {
var data = {
properties: [],
getItem: function(id) {
for (var i = 0; i < productData.length; i++) {
for (var j = 0; j < productData[i].items.length; j++) {
if (productData[i].items[j].id == id) {
return productData[i].items[j];
}
}
}
return null;
},
deleteItem: function(id) {
for (var i = 0; i < productData.length; i++) {
for (var j = 0; j < productData[i].items.length; j++) {
if (productData[i].items[j].id == id) {
productData[i].items.splice(j, 1);
}
}
}
},
getProp: function (id, prop) {
for (var i = 0; i < productData.length; i++) {
for (var j = 0; j < productData[i].items.length; j++) {
if (productData[i].items[j].id == id) {
return productData[i].items[j][prop];
}
}
}
return "";
},
getAndRemoveDataProp: function(prop) {
for (var i = 0; i < this.properties.length; i++) {
if (this.properties[i].propName == prop) {
var result = this.properties[i].propVal;
this.properties.splice(i, 1);
return result;
}
}
return "";
},
total: 0,
getSubtotal: function(id, quantity) {
var price = this.getProp(id, "price") * quantity;
this.total += price;
return price;
}
}
for (var prop in reqData) {
data.properties.push({propName: prop, propVal: reqData[prop]})
}
return data;
}
這似乎工作。我改變了Adam的代碼在3000上聽,錯誤消失了。非常感謝Peter! –