2013-05-26 68 views
0

我試圖根據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; 
} 

回答

6

UNIX要求在運行爲root不到1024更改端口上的網絡端口監聽你的程序就像一個更高的端口的進程3000.

+0

這似乎工作。我改變了Adam的代碼在3000上聽,錯誤消失了。非常感謝Peter! –

0

我在Win 7中通過Adam Freeman的「Pro Javascript for Web Apps」安裝過程中遇到了同樣的問題。

的解決方案是相同的 - 從端口80在server.js文件變化:

例如

http.createServer(handleRequest).listen(3000); 
console.log("Ready on port 3000"); 

工作很好。