2016-03-26 34 views
2

時出於某種原因不是函數,當我運行npm start並且我點擊瀏覽器時,出現此錯誤的堆棧跟蹤。

類型錯誤:$就不是一個函數

at getLocationFromIp (G:\Github\Expressjs\nodetest1\routes\index.js:13:7) 
at G:\Github\Expressjs\nodetest1\routes\index.js:24:14 

會有人能告訴我爲什麼嗎?這是我的代碼。謝謝!

var express = require('express'); 
var router = express.Router(); 
var externalip = require('external-ip'); 
var $ = require('jquery'); 

getLocationFromIp = function() { 
    $.ajax({ 
     url:"freegeoip.net/json/", 
     type: "GET", 
     data: null, 
     dataType: "json", 
     success: function(){console.log("success!")} 
    }); 
} 

router.get('/', function(req, res) { 
    var ip = getLocationFromIp(); 
    res.render('index', { 'ip' : "hi"}); 
}); 
+0

試着在$(document).ready(function(){})函數中添加代碼 – Dale

+0

@Dale - 什麼'document'? – Quentin

+0

問題可能在於通過require函數同步加載Jquery。有沒有一種方法可以在JQuery腳本加載後觸發getLocationFromIp函數?這有可能解決你的問題。 – Elvanos

回答

5

the documentation

For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as jsdom. This can be useful for testing purposes.

var externalip = require('external-ip'); 

require("jsdom").env("", function(err, window) { 
    if (err) { 
     console.error(err); 
     return; 
    } 
    var $ = require("jquery")(window); 

    function getLocationFromIp() { 
     $.ajax({ 
      url: "freegeoip.net/json/", 
      type: "GET", 
      data: null, 
      dataType: "json", 
      success: function() { 
       console.log("success!") 
      }, 
      error: function() { 
       console.log("error", arguments[2]) 
      } 
     }); 
    } 
    var ip = getLocationFromIp(); 
    console.log(ip); 
}); 

你可能會更好用的設計從一開始就節點,例如如request工作的HTTP庫。

+0

這意味着我將不得不運行npm install jsdom?這將如何發生?負載? –

+0

是的,你需要安裝jsdom才能使用它。 'onload'在這種情況下是沒有意義的,沒有什麼是加載的。您只需在啓動服務器之前設置jQuery。正如我所說的,你最好使用不同的庫來發出HTTP請求,這會更簡單。 – Quentin

+0

如果它缺少一個文檔,那麼一種解決方案就是簡單地將這個ajax調用移動到客戶端呢? –

0

如果您正在使用jquery來創建一個http請求,您可以使用http或請求節點模塊來完成此操作。

var express = require('express'); 
var router = express.Router(); 
var externalip = require('external-ip'); 
var http = require('http'); 

getLocationFromIp = function(done) { 
    var options = { 
    host: "freegeoip.net", 
    port: 80, 
    path: "/json" 
    }; 

    var request = http.get(options, function(response) { 
    var result = ""; 
    var responseCode = response.statusCode; 

    response.on('data', function(data) { 
     result += data; 
    }); 

    response.on('end', function() { 
     if(responseCode >= 400) 
     return done(result, null); 
     else 
     return done(false, JSON.parse(result)); 
    }); 
    }); 

    request.on("error", function(error){ 
    return done("Error handling error", null); 
    }); 

    request.end(); 
} 

router.get('/', function(req, res) { 
    var ip = getLocationFromIp(function(error, ip){ 
     res.render('index', { 'ip' : "hi"}); 
    }); 
});