2016-03-26 13 views
2

çağrıldığında bir işlev değil, bu hatayla bu yığın izini alıyorum.

TypeError: $ .ajax

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

birisi bana neden söylemek mümkün olurdu bir işlev değil? İşte benim kodum. Teşekkürler!

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

deneyin (function() {}) işlevi – Dale

+0

@Dale - Ne 'document'? – Quentin

+0

Sorun muhtemelen, Jquery'nin gereksinim işlevi aracılığıyla bir senkronizasyon yüklemesiyle ilgilidir. GetJocationFromIp işlevi AFTER Jquery komut dosyası yüklerini tetiklemenin bir yolu var mı? Senin problemini çözmek gibi. – Elvanos

cevap

5

the documentation bakınız:

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); 
}); 

Muhtemelen en başından itibaren Düğüm, örneğin request olarak çalışmak üzere tasarlanmış bir HTTP kitaplığı kullanarak daha iyi olurdu.

+0

ile jQuery kullanmayın, npm install jsdom'ı da çalıştırmam gerekir? ve bu nasıl ateşlenir? onLoad? –

+0

Evet, bunu kullanabilmek için jsdom'ı yüklemelisiniz. 'yük 'bu bağlamda bir anlam ifade etmiyor, hiçbir şey yüklenmiyor. Sunucuyu çalıştırmadan önce jQuery'yi ayarlamanız yeterlidir. Dediğim gibi, HTTP istekleri yapmak için farklı bir kütüphane kullanmaktan daha iyi olursunuz, çok daha kolay olurdu. – Quentin

+0

Eğer bir belgenin eksik olması durumunda, o zaman bir çözüm, bu ajax çağrısını müşteri tarafına taşımak yerine sadece bir çözüm olurdu? –

0

Yalnızca bir http isteği yapmak için jquery kullanıyorsanız, bunun yerine http veya istek düğüm modülünü kullanabilirsiniz. $ (Document) .ready içinde kod ekleme

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"}); 
    }); 
});