Kann ich jQuery mit Node.js verwenden?

574

Ist es möglich, jQuery-Selektoren / DOM-Manipulationen auf der Serverseite mit Node.js zu verwenden?

John
quelle
3
Ich frage mich: Warum auf der Serverseite verwenden, während Sie es auf der Clientseite tun können?
Inanc Gumus
31
Vielleicht möchten Sie einen Web-Scrapper erstellen, der in regelmäßigen Abständen bestimmte Informationen verschrottet und die Ergebnisse in einer Datenbank speichert? Dies wäre auf Kundenseite nicht so praktisch.
Trevor
2
Sie sollten sich auch Phantomjs ansehen, mit denen Sie eine Browser-Serverseite mit der V8-Engine emulieren können.
Dimitri Kopriwa
2
@deeperx DOM-Manipulationen auf der Serverseite können beim Erstellen eines Crawlers hilfreich sein. Siehe diese Antwort .
Lucio Paiva
JA - sehen Sie sich diese Antwort an - ich bevorzuge die Verwendung von Cheerio, da Sie die volle Leistung des jQuery-Selektors erhalten.
monika mevenkamp

Antworten:

563

Update (27.06.18) : Es sieht so aus, als ob es ein größeres Update gab, jsdomdas dazu führt, dass die ursprüngliche Antwort nicht mehr funktioniert. Ich habe diese Antwort gefunden, die erklärt, wie man sie jsdomjetzt benutzt. Ich habe den entsprechenden Code unten kopiert.

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

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

Hinweis: In der ursprünglichen Antwort wird nicht erwähnt, dass Sie jsdom ebenfalls mit installieren müssennpm install jsdom

Update (Ende 2013) : Das offizielle jQuery-Team übernahm schließlich die Verwaltung des jqueryPakets auf npm:

npm install jquery

Dann:

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

Philippe Rathé
quelle
43
Ist es möglich, jQuery ajax aus node.js mit diesem npm-Modul zu verwenden?
Ajsie
22
Wird nicht unter Windows installiert (ohne nennenswerte Arbeit). In diesem Fall würde ich das Cheerio-Modul empfehlen: matthewmueller.github.com/cheerio
Simon East
7
+1 für das Zeigen, wo man npm bekommt :) Die meisten Leute haben die schlechte Angewohnheit, nur Dinge zu erwähnen, als ob es eine Selbstverständlichkeit sein sollte (gesunder Menschenverstand)
Val
12
Dies kehrt zurück require("...").env is not a function.
Banderi
4
@Banderi das gleiche mit mir, eine Idee? der Fehler:TypeError: require(...).env is not a function
coderInrRain
58

Ja, Sie können eine von mir erstellte Bibliothek namens nodeQuery verwenden

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);
Thomas Blobaum
quelle
20
Beachten Sie, dass nodeQuery die Seite des Benutzers tatsächlich in Echtzeit ändert, sodass sie noch cooler ist als erwartet.
Alessioalex
Ich habe so etwas gesucht, als ich hier gestolpert bin ... Ich habe mir gerade die Pakete nQuery und jquery node angesehen und nQuery wurde vor einem Jahr aktualisiert, als jquery gestern war ... Ist nQuery nicht mehr entwickelt? und wirkt sich jquery auf die clientseitige aus wie nQuery? Hat jemand sie vielleicht beide ausprobiert?
Logan
2
@Logan nQuery ist im Grunde nur jquery. Der Unterschied besteht darin, dass der Code auf dem Server ausgeführt wird und nicht den JQuery-Code an den Browser übermittelt, sondern den Code auf dem Server ausführt und die Dom-Manipulation für verbundene Browser remote ausführt. Beachten Sie auch, dass nQuery ein experimentelles Projekt war, und obwohl ich Pull-Anfragen zur Behebung von Fehlern akzeptieren werde, wurde es nie für einen bestimmten Zweck oder ein bestimmtes Projekt erstellt, sodass es nicht viele Commits hatte
Thomas Blobaum
@ ThomasBlobaum funktioniert nicht für mich, Fehler: , express = Express.createServer();und TypeError: Express.createServer is not a functioneine Idee?
coderInrRain
@ThomasBlobaum sieht so aus, als hätten Sie nicht die neueste Version von Express. Versuchen Sie es npm install --save expressin Ihrer Eingabeaufforderung.
Gilbert-v
55

Zum Zeitpunkt des Schreibens gibt es auch das gepflegte Cheerio .

Schnelle, flexible und schlanke Implementierung von Core-jQuery, das speziell für den Server entwickelt wurde.

Alfred
quelle
2
+1 für Cheerio. Auf der anderen Seite ist es sehr schmerzhaft, jsdom unter Windows zum Laufen zu bringen.
Simon East
1
Kann Cheerio verzögerte Ereignisse und Ajax-Aufrufe verwenden?
Hoffmann
6
unterstützt nicht viele Selektoren wie:gt(1)
chovy
1
Nach meiner Erfahrung funktioniert dieser am besten. Es ist viel schneller als JSDOM.
Jason Prawn
1
@Hoffmann, ich habe eine Sekunde damit verbracht, Dokumente für Sie zu überprüfen. Nein, tut es nicht. Cheerio hat nur DOM-bezogene Methoden.
Denis
39

Mit jsdom können Sie jetzt. Schauen Sie sich einfach das jquery-Beispiel im Beispielverzeichnis an.

Benjamin Coe
quelle
Ein Nachteil von jsdoms jQueryify () ist, dass alle Skripte der Seite ausgeführt werden.
Zeichnen
und es funktioniert nicht unter Windows ohne viele Kopfschmerzen
Jason Goemaat
1
2016 brauchst du jsdom nicht mehr - siehe meine antwort
low_rents
34

Ein einfacher Crawler mit Cheerio

Dies ist meine Formel, um einen einfachen Crawler in Node.js zu erstellen. Dies ist der Hauptgrund für die DOM-Manipulation auf der Serverseite und wahrscheinlich der Grund, warum Sie hierher gekommen sind.

Verwenden Sie zunächst request, um die zu analysierende Seite herunterzuladen. Wenn der Download abgeschlossen ist, gehen Sie zucheerio und beginnen mit der DOM-Manipulation, genau wie mit jQuery.

Arbeitsbeispiel:

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/');

In diesem Beispiel werden alle wichtigen Fragen, die auf der SO-Homepage angezeigt werden, auf der Konsole gedruckt. Deshalb liebe ich Node.js und seine Community. Einfacher geht es nicht :-)

Abhängigkeiten installieren:

npm Installationsanfrage Cheerio

Und führen Sie aus (vorausgesetzt, das obige Skript befindet sich in der Datei crawler.js):

Knoten crawler.js


Codierung

Einige Seiten enthalten nicht englischen Inhalt in einer bestimmten Codierung, und Sie müssen ihn dekodieren UTF-8. Beispielsweise wird eine Seite in brasilianischem Portugiesisch (oder einer anderen Sprache lateinischen Ursprungs) wahrscheinlich in ISO-8859-1(auch bekannt als "latin1") codiert . Wenn eine Dekodierung erforderlich ist, fordere ich Sie requestauf, den Inhalt in keiner Weise zu interpretieren und stattdessen zu verwendeniconv-lite für die Arbeit zu verwenden.

Arbeitsbeispiel:

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/');

Installieren Sie vor dem Ausführen Abhängigkeiten:

npm install request iconv-lite cheerio

Und dann endlich:

Knoten crawler.js


Folgende Links

Der nächste Schritt wäre, Links zu folgen. Angenommen, Sie möchten alle Poster aus jeder Top-Frage auf SO auflisten. Sie müssen zuerst alle Top-Fragen auflisten (Beispiel oben) und dann jeden Link eingeben und die Seite jeder Frage analysieren, um die Liste der beteiligten Benutzer zu erhalten.

Wenn Sie Links folgen, kann eine Rückruf-Hölle beginnen. Um dies zu vermeiden, sollten Sie Versprechen, Futures oder was auch immer verwenden. Ich halte immer asynchron in meinem Werkzeuggürtel. Hier ist ein vollständiges Beispiel für einen Crawler, der Async verwendet:

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

Vor dem Laufen:

npm install request async cheerio

Führen Sie einen Test durch:

Knoten crawler.js

Beispielausgabe:

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

Und das ist die Grundvoraussetzung, die Sie kennen sollten, um Ihre eigenen Crawler zu erstellen :-)


Verwendete Bibliotheken

Lucio Paiva
quelle
22

2016 ist es viel einfacher. Installieren Sie jquery auf node.js mit Ihrer Konsole:

npm install jquery

Binden Sie es an die Variable $(zum Beispiel - ich bin daran gewöhnt) in Ihrem node.js-Code:

var $ = require("jquery");

Sachen machen:

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

funktioniert auch für gulp, da es auf node.js basiert.

low_rents
quelle
Welche Version des Knotens verwenden Sie? Unter Mac Node 6.10.2, jquery 2.2.4 var $ = require("jquery"); $.ajax // undefined (momentan heruntergestimmt).
AJP
@AJP und du bist sicher, dass du es npm install jqueryzuerst getan hast ?
low_rents
1
Ja. > console.log(require("jquery").toString());gibt mir die Factory-Funktion: function ( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); } Ich musste die obige Antwort mit jsdom verwenden: stackoverflow.com/a/4129032/539490
AJP
@ Ajp ok, das ist seltsam.
low_rents
Ich bekomme genau die gleiche Factory-Funktion wie @AJP. Welche Version von jquery haben Sie verwendet, @low_rents?
Boris Burkov
18

Ich glaube, die Antwort darauf lautet jetzt ja.
https://github.com/tmpvar/jsdom

var navigator = { userAgent: "node-js" };  
var jQuery = require("./node-jquery").jQueryInit(window, navigator);
rdzah
quelle
9
Es tut mir leid zu berichten, dass es mehr Arbeit erfordern wird, um jQuery auf jsdom zum Laufen zu bringen. Sizzle funktioniert jedoch! Ich möchte jsdom wirklich so leicht wie möglich halten, daher ist das Hinzufügen einer vollständigen Browser-Emulation wie env.js derzeit keine wirkliche Priorität.
tmpvar
egal, ich habe die modifizierte Kopie gefunden, die mit jsdom gebündelt ist.
Zeichnen
FYI Node-JQuery ist jetzt zugunsten von JQuery veraltet
Ruslan López
1
ReferenceError: Fenster ist nicht definiert
Bonn
17

npm install jquery --save #note ALL 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);
});
Noah
quelle
Das ist die nette Antwort! Bitte stimmen Sie dem zu
datdinhquoc
8

Das jQuery-Modul kann installiert werden mit:

npm install jquery

Beispiel:

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

Referenzen von jQuery in Node.js **:

SUNDARRAJAN K.
quelle
2
Funktioniert bei mir nicht ... C: \ ... \\ Knotenmodule \ jquery \ dist \ jquery.js: 31 neuen Fehler auslösen ("jQuery erfordert ein Fenster mit einem Dokument"); ^ Fehler: jQuery erfordert ein Fenster mit einem Dokument unter module.exports (C: \ ... \ WebContent \ resources \ js \ node_modules \ jquery \ dist \ jquery.js: 31: 12)
Jose Manuel Gomez Alvarez
var jsdom = require ("jsdom"); var window = jsdom.jsdom (). defaultView; jsdom.jQueryify (Fenster " code.jquery.com/jquery.js ", function () {var $ = window. $; $ ("body"). prepend ("<h1> Der Titel </ h1>") ; console.log ($ ("h1"). html ());});
SUNDARRAJAN K
7

Sie müssen das Fenster mit der neuen JSDOM-API abrufen.

const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);
UnchartedWorks
quelle
Das .JSDOM ( ...) sollte für die HTML5-Unterstützung .JSDOM ("<! DOCTYPE html>") sein.
datdinhquoc
2

WARNUNG

Diese von Golo Roden erwähnte Lösung ist nicht korrekt . Es ist nur eine schnelle Lösung, um den Benutzern zu helfen, ihren tatsächlichen jQuery-Code mithilfe einer Node-App-Struktur auszuführen. Es handelt sich jedoch nicht um eine Node-Philosophie, da die jQuery weiterhin auf der Clientseite und nicht auf der Serverseite ausgeführt wird. Es tut mir leid, dass ich eine falsche Antwort gegeben habe.


Sie können Jade auch mit Knoten rendern und Ihren jQuery-Code einfügen. Hier ist der Code der Jade-Datei:

!!! 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();
      });
Timbergus
quelle
4
Downvoted, da in der Frage ausdrücklich angegeben wurde, dass es sich um jQuery auf der Serverseite handelt. Durch einfaches Einbetten von jQuery in eine Jade-Datei wird jQuery weiterhin auf der Clientseite ausgeführt. Daher hilft diese Antwort nicht: - /
Golo Roden
2
OK, vielen Dank. Ich habe es verstanden Ich werde versuchen, es in der Antwort zu klären, um die Leute, die es lesen, nicht zu verwirren. Nochmals vielen Dank für Ihre Hilfe Golo.
Timbergus
2
Bitte :-). Und egal: Wir machen alle unsere Fehler, also keine Sorge :-)
Golo Roden
2

Mein Arbeitscode lautet:

npm install jquery

und dann:

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

oder wenn das Fenster vorhanden ist, dann:

typeof window !== "undefined" ? window : this;
window.jQuery   = require('jquery');
window.$        = window.jQuery;
römisch
quelle
1

Das Modul jsdom ist ein großartiges Werkzeug. Aber wenn Sie ganze Seiten auswerten und auf der Serverseite ein paar funky Sachen machen möchten, schlage ich vor, sie in ihrem eigenen Kontext auszuführen:

vm.runInContext

Dinge wie require/ CommonJSvor Ort werden also Ihren Knotenprozess selbst nicht in die Luft jagen.

Dokumentation finden Sie hier . Prost!

Jakub Oboza
quelle
1

Ab jsdom v10 ist die Funktion .env () veraltet. Ich habe es wie unten beschrieben gemacht, nachdem ich viele Dinge ausprobiert hatte, um eine Abfrage zu erfordern:

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

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

Ich hoffe, dies hilft Ihnen oder allen, die mit solchen Problemen konfrontiert waren.

Plabon Dutta
quelle
TypeError: JSDOM is not a constructor
Nathan Hawks
Wenn Sie jQuery auf der Knotenseite ausführen, installieren Sie zunächst jquery und jsdom mit npm install. Fügen Sie dann die obigen Zeilen in die Datei ein, in der Sie den jquery-Selektor verwenden möchten. Zum Beispiel habe ich a verwendet $.each. Ich habe gerade diese Zeilen eingefügt und es dann wie folgt gemacht: $.each(errors, function (ind,error) { res.send(error.msg);console.log(error.msg); }); Hoffe das hilft !!
Plabon Dutta
Irgendwie hatte sich jsdom entschieden, überhaupt nicht zu installieren. Ich denke, ich finde immer noch npm heraus. Vielen Dank @
Nathan Hawks
0

Keine dieser Lösungen hat mir in meiner Electron App geholfen.

Meine Lösung (Problemumgehung):

npm install jquery

In Ihrer index.jsDatei:

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

.jsSchreiben Sie Ihre jQuery-Funktionen in Ihre Dateien folgendermaßen:

jQuery(document).ready(function() {
Elio Osés
quelle
-1

Nein. Es wird eine ziemlich große Anstrengung sein, eine Browserumgebung auf den Knoten zu portieren.

Ein anderer Ansatz, den ich derzeit für Unit-Tests untersuche, besteht darin, eine "Mock" -Version von jQuery zu erstellen, die bei jedem Aufruf eines Selektors Rückrufe bereitstellt.

Auf diese Weise können Sie Ihre jQuery-Plugins ohne DOM testen. Sie müssen immer noch in echten Browsern testen, um festzustellen, ob Ihr Code in freier Wildbahn funktioniert. Wenn Sie jedoch browserspezifische Probleme entdecken, können Sie diese auch in Ihren Komponententests leicht "verspotten".

Ich werde etwas an github.com/felixge senden, sobald es fertig ist.

Felix Geisendörfer
quelle
Ich mag diese Idee ... es sollte ziemlich einfach sein.
Sudhir Jonathan
-1

Sie können Electron verwenden , es erlaubt hybride Browser und Knoten.

Früher habe ich versucht, canvas2d in nodejs zu verwenden, aber schließlich habe ich aufgegeben. Es wird von NodeJS Standard nicht unterstützt und ist zu schwer zu installieren (viele, viele ... Abhängigkeiten). Bis ich Electron verwende, kann ich problemlos meinen gesamten vorherigen Browser-Code, sogar WebGL, verwenden und den Ergebniswert (z. B. Ergebnis-Base64-Bilddaten) an den Knoten-Code übergeben.

Gonnavis
quelle
-9

Nicht, dass ich davon Wüste. Das DOM ist eine clientseitige Sache (jQuery analysiert nicht den HTML-Code, sondern das DOM).

Hier sind einige aktuelle Node.js-Projekte:

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

Und SimonWs Djangode ist verdammt cool ...

Nosredna
quelle
Ich wünschte es wäre möglich. Ich habe bereits versucht, jquery in ein node.js-Projekt aufzunehmen, und natürlich hat es nicht funktioniert. jQuery basiert auf Dokument / Fenster. Rhino kann die jQuery-Serverseite ausführen : ejohn.org/blog/bringing-the-browser-to-the-server Ich werde nach weiteren Parsern suchen. Vielleicht gibt es eine, die nicht vom Browser abhängt.
John
@ John: Der einzige Grund, warum jQuery unter Rhino ausgeführt werden kann, ist dieses Projekt: github.com/jeresig/env-js/blob/master/src/env.js Es simuliert einen kleinen Teil des DOM und der JavaScript-Laufzeit. Es basiert auf Java-APIs und ist daher ein No-Go für Node.js (das V8 / C ++ verwendet).
Crescent Fresh
2
@Nosredna Während dies wahr war, als Sie es geschrieben haben, ist es eindeutig nicht mehr wahr. Ich schlage vor, dass Sie Ihre Antwort jetzt löschen.
Keith Pinson
-18

Eine Alternative ist die Verwendung von Underscore.js . Es sollte das bereitstellen, was Sie sich von JQuery für den Server gewünscht haben.

John Wright
quelle
10
Können Sie erklären? jQuery bietet unzählige DOM-Manipulations- / Traversing- / Filter-APIs. Der Unterstrich sieht aus wie generische Bibliotheksdienstprogramme, die nichts mit dem DOM zu tun haben.
Peter Lyons
1
Gleich hier sehe ich nicht, wie relevant dies ist. Die beiden sind Ergänzungen, keine Alternativen
Yi Jiang
2
Diese Antwort ist nicht ganz falsch. jQuery und Underscore überschneiden sich: Beide bieten Funktionen wie forEach.
Tuomassalo
8
-1 Sie haben überlappende Funktionen, aber der Unterstrich ist kein jQuery-Ersatz.
Sam
2
Die Frage ist jedoch nach DOM-Manipulationen / Selektoren.
Mikermcneil