Node.js ile jQuery kullanabilir miyim?


574

Node.js kullanarak sunucu tarafında jQuery seçicileri / DOM manipülasyonu kullanmak mümkün müdür?


3
Acaba: İstemci tarafında neden sunucu tarafında kullanıyorsunuz?
İnanç Gümüş

31
Belki belirli bilgileri düzenli aralıklarla not eden ve sonuçları bir veritabanında saklayan bir web kazıyıcı oluşturmak isteyebilirsiniz? Bu, istemci tarafından bu kadar pratik olmayacaktır.
Trevor

2
Ayrıca, V8 motorlu bir tarayıcı sunucusu tarafını taklit etmenize izin veren phantomjs'e de göz atmalısınız.
Dimitri Kopriwa

2
@deeperx Sunucu tarafındaki DOM manipülasyonu, bir tarayıcı oluştururken yararlı olabilir. Bu cevaba bakınız .
Lucio Paiva

EVET - bu cevaba bir göz atın - jQuery seçicinin tüm gücünü elde ettiğiniz için cheerio'yu tercih ederim.
monika mevenkamp

Yanıtlar:


563

Güncelleme (27-Jun-18) : jsdomOrijinal cevabın artık çalışmamasına neden olan büyük bir güncelleme var gibi görünüyor . Şimdi nasıl kullanılacağını açıklayan bu cevabı buldum jsdom. Aşağıdaki ilgili kodu kopyaladım.

var jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;

var $ = jQuery = require('jquery')(window);

Not: Orijinal cevap, jsdom'u da kullanmanız gerektiğini söyleyemez.npm install jsdom

Güncelleme (2013 sonu) : Resmi jQuery ekibi jquerynpm'de paketin yönetimini devraldı:

npm install jquery

Sonra:

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


43
Bu npm modülü ile node.js'den jQuery ajax kullanmak mümkün müdür?
ajsie

22
Windows'a yüklenmez ( önemli bir çalışma olmadan ), bu durumda Cheerio modülünü tavsiye ederim: matthewmueller.github.com/cheerio
Simon East

7
Npm'yi nereden alacağınızı göstermek için +1 :) çoğu insan belirli bir şey gibi sanki kötü şeyler söyleme alışkanlığına sahiptir (sağduyu)
Val

12
Bu geri döner require("...").env is not a function.
Banderi

4
@Banderi benimle aynı, herhangi bir fikir? hata:TypeError: require(...).env is not a function
coderInrRain

58

Evet, nodeQuery adlı bir kitaplık kullanarak

var Express = require('express')
    , dnode = require('dnode')
    , nQuery = require('nodeQuery')
    , express = Express.createServer();

var app = function ($) {
    $.on('ready', function () {
        // do some stuff to the dom in real-time
        $('body').append('Hello World');
        $('body').append('<input type="text" />');
        $('input').live('click', function () {
            console.log('input clicked');
            // ...
        });
    });
};

nQuery
    .use(app);

express
    .use(nQuery.middleware)
    .use(Express.static(__dirname + '/public'))
    .listen(3000);

dnode(nQuery.middleware).listen(express);

20
NodeQuery'nin gerçekte kullanıcının sayfasını gerçek zamanlı değiştirdiğine dikkat edin, bu yüzden beklenenden daha serindir.
alessioalex

Burada tökezlediğimde böyle bir şey arıyordum ... Sadece nQuery ve jquery düğüm paketlerine baktım ve nQuery, jquery'nin dün olduğu bir yıl önce güncellendi ... nQuery artık geliştirilmedi mi? ve jquery nQuery gibi istemci tarafı etkiler mi? İkisini de deneyen var mı?
Logan

2
@Logan nQuery temelde sadece jquery. fark kodun sunucuda çalıştırılması ve jquery kodunu tarayıcıya teslim etmek yerine, kodu sunucuda çalıştırması ve bağlı tarayıcılara dom manipülasyonunu uzaktan yürütmesidir. Ayrıca, nQuery'nin deneysel bir proje olduğunu ve hataları düzeltmek için çekme isteklerini kabul ederken, hiçbir zaman belirli bir amaç veya proje için yaratılmadığından, çok fazla taahhütleri
olmadı

@ThomasBlobaum benim için çalışmıyor, hata: , express = Express.createServer();ve TypeError: Express.createServer is not a functionherhangi bir fikir?
coderInrRain

@ThomasBlobaum, Express'in en son sürümüne sahip olmadığınız anlaşılıyor. npm install --save expressKomut isteminde deneyin .
gilbert-v

55

Yazma sırasında da korunan Cheerio var .

Sunucu için özel olarak tasarlanmış çekirdek jQuery'nin hızlı, esnek ve yalın uygulaması.


2
Cheerio için +1. jsdom, diğer yandan, Windows üzerinde çalışan gerçekten acı verici.
Simon East

1
Cheerio ertelenmiş olayları ve ajax çağrılarını kullanabilir mi?
Hoffmann

6
:gt(1)
chovy

1
Benim tecrübelerime göre bu en iyi sonucu verir. JSDOM'dan çok daha hızlı.
Jason Prawn

1
@Hoffmann, senin için belgeleri kontrol etmek için bir saniye harcadım. Hayır. Cheerio'nun yalnızca DOM ile ilgili yöntemleri vardır.
Denis


34

Cheerio kullanarak basit bir tarayıcı

Bu, Node.js'de basit bir tarayıcı yapmak için formülüm. Sunucu tarafında DOM manipülasyonu yapmak istemenin ana nedeni ve muhtemelen buraya gelmenizin nedeni.

İlk olarak, requestayrıştırılacak sayfayı indirmek için kullanın . İndirme işlemi tamamlandığında, cheeriojQuery gibi DOM işlemesine geçin ve DOM işlemeye başlayın.

Çalışma örneği:

var
    request = require('request'),
    cheerio = require('cheerio');

function parse(url) {
    request(url, function (error, response, body) {
        var
            $ = cheerio.load(body);

        $('.question-summary .question-hyperlink').each(function () {
            console.info($(this).text());
        });
    })
}

parse('http://stackoverflow.com/');

Bu örnek, SO ana sayfasında gösterilen tüm soruları konsola yazdırır. Bu yüzden Node.js ve topluluğunu seviyorum. Bundan daha kolay olamazdı :-)

Bağımlılıkları yükleyin:

npm yükleme isteği cheerio

Ve çalıştırın (yukarıdaki komut dosyasının dosyada olduğunu varsayarak crawler.js):

düğüm crawler.js


Kodlama

Bazı sayfalarda belirli bir kodlamada ingilizce olmayan içerik bulunur ve kodunu çözmeniz gerekir UTF-8. Örneğin, Brezilya Portekizcesi'ndeki (veya latin kökenli başka bir dilde) bir sayfa büyük olasılıkla ISO-8859-1("latin1" olarak) kodlanır . Kod çözme gerektiğinde, requestiçeriği hiçbir şekilde yorumlamamayı ve bunun yerine iconv-liteişi yapmak için kullanmamayı söylerim .

Çalışma örneği:

var
    request = require('request'),
    iconv = require('iconv-lite'),
    cheerio = require('cheerio');

var
    PAGE_ENCODING = 'utf-8'; // change to match page encoding

function parse(url) {
    request({
        url: url,
        encoding: null  // do not interpret content yet
    }, function (error, response, body) {
        var
            $ = cheerio.load(iconv.decode(body, PAGE_ENCODING));

        $('.question-summary .question-hyperlink').each(function () {
            console.info($(this).text());
        });
    })
}

parse('http://stackoverflow.com/');

Çalıştırmadan önce bağımlılıkları yükleyin:

npm yükleme isteği iconv-lite cheerio

Ve son olarak:

düğüm crawler.js


Aşağıdaki bağlantılar

Bir sonraki adım bağlantıları takip etmek olacaktır. Diyelim ki her bir üst sorudaki tüm posterleri SO'da listelemek istiyorsunuz. Öncelikle tüm sık sorulan soruları listelemeniz (yukarıdaki örnek) ve ardından ilgili kullanıcıların listesini almak için her sorunun sayfasını ayrıştırarak her bir bağlantıyı girmeniz gerekir.

Bağlantıları izlemeye başladığınızda, bir geri arama cehennemi başlayabilir. Bundan kaçınmak için bir tür vaat, gelecek veya başka bir şey kullanmalısınız. Hep tutmak asenk benim araç kemerinde bulunan. Yani, async kullanan bir tarayıcının tam örneği:

var
    url = require('url'),
    request = require('request'),
    async = require('async'),
    cheerio = require('cheerio');

var
    baseUrl = 'http://stackoverflow.com/';

// Gets a page and returns a callback with a $ object
function getPage(url, parseFn) {
    request({
        url: url
    }, function (error, response, body) {
        parseFn(cheerio.load(body))
    });
}

getPage(baseUrl, function ($) {
    var
        questions;

    // Get list of questions
    questions = $('.question-summary .question-hyperlink').map(function () {
        return {
            title: $(this).text(),
            url: url.resolve(baseUrl, $(this).attr('href'))
        };
    }).get().slice(0, 5); // limit to the top 5 questions

    // For each question
    async.map(questions, function (question, questionDone) {

        getPage(question.url, function ($$) {

            // Get list of users
            question.users = $$('.post-signature .user-details a').map(function () {
                return $$(this).text();
            }).get();

            questionDone(null, question);
        });

    }, function (err, questionsWithPosters) {

        // This function is called by async when all questions have been parsed

        questionsWithPosters.forEach(function (question) {

            // Prints each question along with its user list
            console.info(question.title);
            question.users.forEach(function (user) {
                console.info('\t%s', user);
            });
        });
    });
});

Koşudan önce:

npm yükleme isteği zaman uyumsuz cheerio

Bir test yapın:

düğüm crawler.js

Örnek çıktı:

Is it possible to pause a Docker image build?
    conradk
    Thomasleveil
PHP Image Crop Issue
    Elyor
    Houston Molinar
Add two object in rails
    user1670773
    Makoto
    max
Asymmetric encryption discrepancy - Android vs Java
    Cookie Monster
    Wand Maker
Objective-C: Adding 10 seconds to timer in SpriteKit
    Christian K Rider

Ve kendi tarayıcılarınızı yapmaya başlamak için bilmeniz gereken temel bu :-)


Kullanılan kütüphaneler


22

2016'da işler çok daha kolay. konsolunuzla node.js'ye jquery yükleyin:

npm install jquery

$node.js kodunuzdaki değişkene bağlayın (örneğin - alışkınım):

var $ = require("jquery");

şeyler yapmak:

$.ajax({
    url: 'gimme_json.php',
    dataType: 'json',
    method: 'GET',
    data: { "now" : true }
});

ayrıca node.js'ye dayandığı için gulp için de çalışır.


Hangi düğüm sürümünü kullanıyorsunuz? Mac'te, Düğüm 6.10.2, jquery 2.2.4, var $ = require("jquery"); $.ajax // undefined (Şu an için aşağı oy verildi).
AJP

@AJP ve npm install jqueryilk yaptığınızdan emin misiniz ?
low_rents

1
Evet. > console.log(require("jquery").toString());bana fabrika fonksiyonunu veriyor: function ( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); } Yukarıdaki cevabı jsdom ile kullanmak zorunda kaldım: stackoverflow.com/a/4129032/539490
AJP

@AJP tamam, bu garip.
low_rents

@AJP ile tam olarak aynı fabrika fonksiyonunu alıyorum. Hangi jquery sürümünü kullandınız, @low_rents?
Boris Burkov

18

Bunun cevabının şimdi evet olduğuna inanıyorum.
https://github.com/tmpvar/jsdom

var navigator = { userAgent: "node-js" };  
var jQuery = require("./node-jquery").jQueryInit(window, navigator);

9
JQuery jsdom üzerinde çalışan almak için daha fazla iş alacağını rapor için üzgünüm. Ancak Sizzle işe yarıyor! Gerçekten jsdom'u olabildiğince hafif tutmak istiyorum, bu yüzden env.js gibi tam tarayıcı öykünmesini eklemek şu anda gerçekten bir öncelik değil.
tmpvar

boş ver, ben jsdom ile birlikte değiştirilmiş kopya bulundu.
drewish

FYI node-jquery artık jquery lehine kullanımdan kaldırıldı
Ruslan López

1
ReferenceError: pencere tanımlanmadı
Bonn

17

npm install jquery --save #note TÜM LOWERCASE

npm install jsdom --save

const jsdom = require("jsdom");
const dom = new jsdom.JSDOM(`<!DOCTYPE html>`);
var $ = require("jquery")(dom.window);


$.getJSON('https://api.github.com/users/nhambayi',function(data) {
  console.log(data);
});

bu temiz cevap! pls bunu oyla
datdinhquoc

8

jQuery modülü kullanılarak kurulabilir:

npm install jquery

Misal:

var $ = require('jquery');
var http = require('http');

var options = {
    host: 'jquery.com',
    port: 80,
    path: '/'
};

var html = '';
http.get(options, function(res) {
res.on('data', function(data) {
    // collect the data chunks to the variable named "html"
    html += data;
}).on('end', function() {
    // the whole of webpage data has been collected. parsing time!
    var title = $(html).find('title').text();
    console.log(title);
 });
});

JQuery'nin Node.js ** referansları:


2
Benim için çalışmıyor ... C: \ ... \\ node_modules \ jquery \ dist \ jquery.js: 31 yeni bir hata atın ("jQuery bir belge içeren bir pencere gerektirir"); ^ Hata: jQuery, module.exports'ta bir belgeye sahip bir pencere gerektirir (C: \ ... \ WebContent \ resources \ js \ node_modules \ jquery \ dist \ jquery.js: 31: 12)
Jose Manuel Gomez Alvarez

var jsdom = gerektirir ("jsdom"); var window = jsdom.jsdom (). defaultView; jsdom.jQueryify (pencere, " code.jquery.com/jquery.js ", function () {var $ = window. $; $ ("body"). prepend ("<h1> Başlık </h1>") konsol.log ($ ("h1"). html ());});
SUNDARRAJAN K

7

Pencereyi yeni JSDOM API'sını kullanarak almanız gerekir.

const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);

...HTML5 desteği için .JSDOM ( ) .JSDOM ("<! DOCTYPE html>") olmalıdır?
datdinhquoc

2

UYARI

Golo Roden'in belirttiği gibi bu çözüm doğru değil . İnsanların gerçek jQuery kodlarını bir Düğüm uygulama yapısı kullanarak çalıştırmasına yardımcı olmak için hızlı bir çözümdür, ancak jQuery hala sunucu tarafında değil istemci tarafında çalışıyor. Yanlış cevap verdiğim için özür dilerim.


Ayrıca Jade'i düğüm ile oluşturabilir ve jQuery kodunuzu içine koyabilirsiniz. Yeşim dosyasının kodu:

!!! 5
html(lang="en")
  head
    title Holamundo!
    script(type='text/javascript', src='http://code.jquery.com/jquery-1.9.1.js')
  body
    h1#headTitle Hello, World
    p#content This is an example of Jade.
    script
      $('#headTitle').click(function() {
        $(this).hide();
      });
      $('#content').click(function() {
        $(this).hide();
      });

4
Soru açıkça sunucu tarafında jQuery ile ilgili olduğunu belirtti. Sadece jQuery bir yeşim dosyasına gömmek jQuery hala istemci tarafında çalıştırılır. Bu nedenle, bu cevap yardımcı olmaz: - /
Golo Roden 31:13

2
Tamam çok teşekkür ederim. Anladım. Onu okuyan insanları karıştırmamak için cevabı netleştirmeye çalışacağım. Yardımınız için tekrar teşekkürler Golo.
Timbergus

2
Rica ederim :-). Ve boş verin: Hepimiz hatalarımızı yaparız, bu yüzden endişelenmeyin :-)
Golo Roden

2

Çalışma kodum:

npm install jquery

ve sonra:

global.jQuery   = require('jquery');
global.$        = global.jQuery;

veya pencere mevcutsa, o zaman:

typeof window !== "undefined" ? window : this;
window.jQuery   = require('jquery');
window.$        = window.jQuery;

1

Jsdom modülü harika bir araçtır. Ancak tüm sayfaları değerlendirmek ve sunucu tarafında bazı funky şeyler yapmak istiyorsanız, bunları kendi bağlamlarında çalıştırmanızı öneririz:

vm.runInContext

Bu yüzden require/ CommonJSsitede gibi şeyler Düğüm sürecinizi kendi başına uçurmayacaktır.

Belgeleri burada bulabilirsiniz . Şerefe!


1

Jsdom v10 itibariyle .env () işlevi kullanımdan kaldırılmıştır. Ben jquery gerektiren bir çok şey denedikten sonra aşağıdaki gibi yaptım:

var jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;

var $ = jQuery = require('jquery')(window);

Umarım bu size veya bu tür sorunlarla karşılaşan herkese yardımcı olur.


TypeError: JSDOM is not a constructor
Nathan Hawks

Düğüm tarafında jQuery çalıştırıyorsanız, npm install kullanarak jquery ve jsdom kurun. Ardından, jquery seçicisini kullanmaya çalıştığınız dosyaya yukarıdaki satırları ekleyin. Örneğin, a kullandım $.each. Ben sadece bu satırları dahil ve sonra aşağıdaki gibi yaptım: $.each(errors, function (ind,error) { res.send(error.msg);console.log(error.msg); }); Umarım bu yardımcı olur !!
Plabon Dutta

Bir şekilde jsdom hiç yüklememeye karar vermişti. Sanırım hala npm'i buluyorum. Teşekkürler @
Nathan Hawks


0

Bu çözümlerin hiçbiri Electron Uygulamamda bana yardımcı olmadı.

Çözümüm (geçici çözüm):

npm install jquery

Senin içinde index.jsdosyaya:

var jQuery = $ = require('jquery');

Senin içinde .jsdosyaların bu şekilde sizinki jQuery fonksiyonları yazın:

jQuery(document).ready(function() {


-1

Hayır. Bir tarayıcı ortamını düğüme taşımak oldukça büyük bir çaba olacaktır.

Şu anda birim testi için araştırıyorum başka bir yaklaşım, bir seçici her çağrıldığında geri aramalar sağlayan jQuery "Mock" sürümünü oluşturmaktır.

Bu şekilde jQuery eklentilerinizi DOM olmadan birim test edebilirsiniz. Kodunuzun vahşi ortamda çalışıp çalışmadığını görmek için gerçek tarayıcılarda test etmeniz gerekecek, ancak tarayıcıya özgü sorunları keşfederseniz, birim testlerinizdekileri de kolayca "taklit edebilirsiniz".

Gösterilmeye hazır olduğunda bir şeyi github.com/felixge adresine göndereceğim.


Bu fikri seviyorum ... Yapması oldukça kolay olmalı.
Sudhir Jonathan

-1

Electron'u kullanabilirsiniz , hibrit tarayıcılara ve düğümlere izin verir.

Daha önce nodejlerde canvas2d kullanmaya çalıştım, ama sonunda vazgeçtim. Varsayılan olarak nodejs tarafından desteklenmez ve kurulumu çok zordur (birçok ... bağımlı). Elektron'u kullanana kadar, önceki tüm tarayıcı kodumu, hatta WebGL'yi kolayca kullanabilir ve sonuç değerini (örn. Sonuç base64 görüntü verileri) nodejs koduna geçirebilirim.


-9

Bildiğim kadarıyla hayır. DOM, istemci tarafı bir şeydir (jQuery, HTML'yi ayrıştırmaz, ancak DOM'yi).

İşte bazı güncel Node.js projeleri:

https://github.com/ry/node/wiki ( https://github.com/nodejs/node )

Ve SimonW'nin djangode'u çok havalı ...


Keşke mümkün olsaydı. Zaten bir node.js projesinde jquery dahil denedim ve tabii ki işe yaramadı. jQuery belge / pencereye dayanır. Rhino jQuery sunucu tarafını çalıştırabilir: ejohn.org/blog/bringing-the-browser-to-the-server Daha fazla ayrıştırıcı arayacağım. Belki tarayıcıya bağlı olmayan bir tane var.
John

@John: jQuery'nin Rhino'da çalışmasının tek nedeni bu projeden kaynaklanıyor: github.com/jeresig/env-js/blob/master/src/env.js DOM ve JavaScript çalışma zamanının küçük bir bölümünü simüle ediyor. Java API'lerine dayanır, bu nedenle Node.js (V8 / C ++ kullanan) için bir işlem değildir.
Crescent Fresh

2
@Nosredna Yazarken bu doğru olsa da, artık doğru değil. Cevabınızı şimdi silmenizi öneririm.
Keith Pinson

-18

Alternatif olarak Underscore.js kullanmaktır . JQuery'den sunucu tarafı istemiş olabileceğinizi sağlamalıdır.


10
Açıklayabilir misin? jQuery tonlarca DOM manipülasyon / çaprazlama / filtreleme API'sı sağlar. Alt çizgi, DOM ile ilgisi olmayan genel kütüphane yardımcı programlarına benziyor.
Peter Lyons

1
Burada aynı, bunun ne kadar alakalı olduğunu görmüyorum, ikisinin tamamlayıcısı, alternatif değil
Yi Jiang

2
Bu cevap tamamen yanlış değil. jQuery ve Alt çizgi çakışıyor: her ikisi de forEach gibi özellikler sağlıyor.
tuomassalo

8
-1 Çakışan işlevsellikleri var, ancak Underscore bir jQuery değiştirme değil.
Sam

2
Soru, DOM manipülasyonu / seçicileri hakkında sormaktır.
mikermcneil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.