2016-03-26 37 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"}); 
    }); 
});