Zastanawiam się: po co korzystać po stronie serwera, skoro można to zrobić po stronie klienta?
Inanc Gumus
31
Być może możesz chcieć utworzyć skrobak internetowy, który w regularnych odstępach czasu usuwa określone informacje i przechowuje wyniki w bazie danych? Nie byłoby to tak praktyczne ze strony klienta.
Trevor
2
Powinieneś także spojrzeć na phantomjs, które pozwalają emulować stronę przeglądarki za pomocą silnika V8.
Dimitri Kopriwa
2
Manipulacja DOM @deeperx DOM po stronie serwera może być użyteczna podczas tworzenia przeszukiwacza. Zobacz tę odpowiedź .
Lucio Paiva,
TAK - spójrz na tę odpowiedź - wolę to niż używanie cheerio, ponieważ masz pełną moc selektora jQuery.
monika mevenkamp
Odpowiedzi:
563
Aktualizacja (27 czerwca-18) : Wygląda na to, że nastąpiła poważna aktualizacja, jsdomktóra powoduje, że pierwotna odpowiedź nie działa. Znalazłem tę odpowiedź, która wyjaśnia, jak korzystać jsdomteraz. Skopiowałem odpowiedni kod poniżej.
Zauważ, że nodeQuery zmienia stronę użytkownika w czasie rzeczywistym, więc jest jeszcze fajniejszy, niż można się spodziewać.
alessioalex,
Szukałem czegoś takiego, kiedy natknąłem się tutaj ... Właśnie spojrzałem na pakiety nQuery i węzłów jquery, a nQuery zostało zaktualizowane rok temu, gdzie wczoraj była jquery ... Czy nQuery nie jest już rozwijany? i czy jquery wpływa na stronę klienta, podobnie jak nQuery? Czy ktoś może próbował ich obu?
Logan,
2
@Logan nQuery to po prostu jquery. różnica polega na tym, że kod jest uruchamiany na serwerze i zamiast dostarczać kod jquery do przeglądarki, uruchamia kod na serwerze i zdalnie wykonuje manipulację domem na podłączonych przeglądarkach. Zauważ też, że nQuery był projektem eksperymentalnym i chociaż przyjmuję żądania ściągania w celu naprawy błędów, nigdy nie został stworzony do żadnego konkretnego celu lub projektu, więc nie miał wielu zobowiązań
Thomas Blobaum
@ThomasBlobaum nie działa dla mnie, błąd: , express = Express.createServer();i TypeError: Express.createServer is not a functionjakiś pomysł?
coderInrRain
@ThomasBlobaum wygląda na to, że nie masz najnowszej wersji Express. Spróbuj npm install --save expressw wierszu polecenia.
gilbert-v
55
W momencie pisania jest również utrzymane Cheerio .
Szybka, elastyczna i oszczędna implementacja podstawowego jQuery zaprojektowanego specjalnie dla serwera.
To jest moja formuła na stworzenie prostego robota w Node.js. Jest to główny powód, dla którego chcesz wykonywać manipulacje DOM po stronie serwera i prawdopodobnie jest to powód, dla którego tu trafiłeś.
Najpierw użyj, requestaby pobrać stronę do przeanalizowania. Po zakończeniu pobierania obsłuż go cheerioi rozpocznij manipulację DOM, tak jak przy użyciu jQuery.
Ten przykład wydrukuje w konsoli wszystkie najważniejsze pytania wyświetlane na stronie głównej SO. Właśnie dlatego uwielbiam Node.js i jego społeczność. Nie może być łatwiej :-)
Zainstaluj zależności:
npm cheerio żądanie instalacji
I uruchom (zakładając, że powyższy skrypt znajduje się w pliku crawler.js ):
węzeł crawler.js
Kodowanie
Niektóre strony będą zawierać treści w języku innym niż angielski w pewnym kodowaniu i konieczne będzie ich odkodowanie UTF-8. Na przykład strona w portugalskim języku brazylijskim (lub innym języku pochodzenia łacińskiego) prawdopodobnie będzie zakodowana w ISO-8859-1(inaczej „latin1”). Kiedy potrzebne jest dekodowanie, mówię, requestaby nie interpretować treści w żaden sposób i zamiast tego używaćiconv-lite do wykonania zadania.
Przykład roboczy:
var
request = require('request'),
iconv = require('iconv-lite'),
cheerio = require('cheerio');var
PAGE_ENCODING ='utf-8';// change to match page encodingfunction 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/');
Przed uruchomieniem zainstaluj zależności:
npm żądanie instalacji iconv-lite cheerio
A potem w końcu:
węzeł crawler.js
Poniższe linki
Następnym krokiem będzie skorzystanie z linków. Powiedz, że chcesz wyświetlić listę wszystkich plakatów z każdego górnego pytania w SO. Najpierw musisz wymienić wszystkie najważniejsze pytania (przykład powyżej), a następnie wprowadzić każdy link, analizując stronę każdego pytania, aby uzyskać listę zaangażowanych użytkowników.
Kiedy zaczniesz podążać za linkami, możesz zacząć piekło zwrotne . Aby tego uniknąć, powinieneś użyć obietnic, przyszłości lub cokolwiek innego. Zawsze trzymam asynchronię w pasku narzędzi. Oto pełny przykład robota używającego asynchronizacji:
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 $ objectfunction 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 questionasync.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);});});});});
Przed uruchomieniem:
npm żądanie instalacji asynchroniczne cheerio
Uruchom test:
węzeł crawler.js
Przykładowe dane wyjściowe:
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
I to jest podstawa, którą powinieneś wiedzieć, aby zacząć tworzyć własne roboty :-)
Jakiej wersji węzła używasz? Na Macu, Node 6.10.2, jquery 2.2.4, var $ = require("jquery"); $.ajax // undefined (Na razie głosowanie negatywne).
AJP
@AJP i jesteś pewien, że zrobiłeś npm install jquerypierwszy?
low_rents
1
Tak. > console.log(require("jquery").toString());daje mi funkcję fabryczną: function ( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); } musiałem użyć powyższej odpowiedzi z jsdom: stackoverflow.com/a/4129032/539490
AJP
@AJP ok, to dziwne.
low_rents
Dostaję dokładnie taką samą funkcję fabryczną jak @AJP. Jakiej wersji jquery użyłeś, @low_rents?
Przykro mi informować, że uruchomienie jQuery na jsdom wymaga więcej pracy. Skwierczenie jednak działa! Naprawdę chcę zachować jsdom tak lekki, jak to możliwe, więc dodanie pełnej emulacji przeglądarki, takiej jak env.js, nie jest w tej chwili tak naprawdę priorytetem.
tmpvar
nieważne, znalazłem zmodyfikowaną kopię dołączoną do jsdom.
zremisował
FYI węzeł-jquery jest teraz przestarzałe na rzecz jquery
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);});});
.JSDOM ( ...) powinien być .JSDOM („<! DOCTYPE html>”) dla obsługi HTML5?
datdinhquoc
2
OSTRZEŻENIE
To rozwiązanie, o którym wspomniał Golo Roden, jest nieprawidłowe . Jest to tylko szybka poprawka, aby pomóc ludziom uruchomić ich rzeczywisty kod jQuery za pomocą struktury aplikacji Node, ale nie jest to filozofia Node, ponieważ jQuery nadal działa po stronie klienta, a nie po stronie serwera. Przepraszam za udzielenie złej odpowiedzi.
Możesz także wyrenderować Jade z węzłem i umieścić w nim swój kod jQuery. Oto kod pliku jadeit:
!!!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 ofJade.
script
$('#headTitle').click(function(){
$(this).hide();});
$('#content').click(function(){
$(this).hide();});
Zagłosowano, ponieważ w pytaniu wyraźnie stwierdzono, że chodzi o jQuery po stronie serwera. Po prostu osadzając jQuery w jadeitowym pliku, jQuery jest nadal uruchamiany po stronie klienta. Dlatego ta odpowiedź nie pomaga: - /
Golo Roden
2
Ok, bardzo dziękuję. Rozumiem to. Spróbuję wyjaśnić to w odpowiedzi, aby nie mylić osób, które ją czytają. Jeszcze raz dziękuję za pomoc Golo.
Timbergus
2
Nie ma za co :-). I nieważne: wszyscy popełniamy błędy, więc nie martw się :-)
Moduł jsdom jest doskonałym narzędziem. Ale jeśli chcesz ocenić całe strony i zrobić trochę funky po stronie serwera, sugeruję uruchomienie ich we własnym kontekście:
vm.runInContext
Tak więc rzeczy takie jak require/ CommonJSon site nie wysadzą samego procesu węzła.
Jeśli korzystasz z jQuery po stronie węzła, najpierw zainstaluj jquery i jsdom przy użyciu npm install. Następnie dodaj powyższe wiersze do pliku, w którym próbujesz użyć selektora jquery. Na przykład użyłem $.each. Właśnie zamieściłem te linie, a potem zrobiłem to tak: $.each(errors, function (ind,error) { res.send(error.msg);console.log(error.msg); }); Mam nadzieję, że to pomaga !!
Plabon Dutta
Jakoś jsdom postanowił w ogóle nie instalować. Chyba wciąż zastanawiam się nad npm. Dzięki @
Nie. Przeniesienie środowiska przeglądarki do węzła będzie dość dużym wysiłkiem.
Innym podejściem, które obecnie badam pod kątem testów jednostkowych, jest stworzenie „próbnej” wersji jQuery, która zapewnia wywołania zwrotne przy każdym wywołaniu selektora.
W ten sposób możesz jednostkowo przetestować wtyczki jQuery bez posiadania DOM. Nadal będziesz musiał przetestować w prawdziwych przeglądarkach, aby sprawdzić, czy Twój kod działa na wolności, ale jeśli odkryjesz specyficzne problemy z przeglądarką, możesz łatwo „wyśmiewać” je w testach jednostkowych.
Pchnę coś na github.com/felixge, gdy będzie gotowe do pokazania.
Podoba mi się ten pomysł ... powinien być łatwy do zrobienia.
Sudhir Jonathan
-1
Możesz użyć Electron , pozwala on na hybrydowe przeglądarki i nodejs.
Wcześniej próbowałem używać canvas2d w nodejs, ale w końcu się poddałem. Nie jest obsługiwany przez domyślny nodejs i jest zbyt trudny do zainstalowania (wiele wielu ... zależności). Dopóki nie użyję Electron, mogę z łatwością używać całego mojego poprzedniego kodu przeglądarki, nawet WebGL, i przekazać wartość wyniku (np. Wynik obrazu base64 obrazu) do kodu nodejs.
Chciałbym, żeby to było możliwe. Próbowałem już dołączyć jquery do projektu node.js i oczywiście nie działało. jQuery jest oparty na dokumencie / oknie. Rhino jest w stanie uruchomić stronę jQuery po stronie serwera: ejohn.org/blog/bringing-the-browser-to-the-server. Będę szukał więcej parserów. Może jest taki, który nie zależy od przeglądarki.
Jan
@John: jedynym powodem, dla którego jQuery może działać na Rhino, jest ten projekt: github.com/jeresig/env-js/blob/master/src/env.js Symuluje niewielką część DOM i środowiska wykonawczego JavaScript. Opiera się na Java apis, więc nie jest to konieczne dla Node.js (który używa V8 / C ++).
Crescent Fresh
2
@Nosredna Chociaż mogło to być prawdą, kiedy to napisałeś, to oczywiście nie jest już prawdą. Sugeruję, aby usunąć swoją odpowiedź teraz.
Keith Pinson
-18
Alternatywą jest użycie Underscore.js . Powinien dostarczać to, czego mogłeś chcieć po stronie serwera od JQuery.
Możesz wytłumaczyć? jQuery zapewnia mnóstwo interfejsów API do manipulacji / przeszukiwania / filtrowania DOM. Podkreślenie wygląda jak ogólne narzędzia biblioteczne, które nie mają nic wspólnego z DOM.
Peter Lyons,
1
To samo tutaj, nie widzę, jak to jest istotne, oba są uzupełnieniami, a nie alternatywami
Yi Jiang
2
Ta odpowiedź nie jest całkowicie błędna. jQuery i Underscore nakładają się: oba zapewniają funkcje takie jak forEach.
tuomassalo
8
-1 Mają funkcję nakładania się, ale podkreślenie nie zastępuje jQuery.
Sam
2
Pytanie dotyczy jednak manipulacji / selektorów DOM.
Odpowiedzi:
Aktualizacja (27 czerwca-18) : Wygląda na to, że nastąpiła poważna aktualizacja,
jsdom
która powoduje, że pierwotna odpowiedź nie działa. Znalazłem tę odpowiedź, która wyjaśnia, jak korzystaćjsdom
teraz. Skopiowałem odpowiedni kod poniżej.Uwaga: Oryginalna odpowiedź nie wspomina, że będziesz musiał zainstalować jsdom również za pomocą
npm install jsdom
Aktualizacja (pod koniec 2013 r.) : Oficjalny zespół jQuery ostatecznie przejął zarządzanie
jquery
pakietem na npm:Następnie:źródło
require("...").env is not a function
.TypeError: require(...).env is not a function
Tak, możesz, korzystając z utworzonej przeze mnie biblioteki o nazwie nodeQuery
źródło
, express = Express.createServer();
iTypeError: Express.createServer is not a function
jakiś pomysł?npm install --save express
w wierszu polecenia.W momencie pisania jest również utrzymane Cheerio .
źródło
:gt(1)
Za pomocą jsdom możesz teraz. Wystarczy spojrzeć na ich przykład jquery w katalogu przykładów.
źródło
Prosty robot wykorzystujący Cheerio
To jest moja formuła na stworzenie prostego robota w Node.js. Jest to główny powód, dla którego chcesz wykonywać manipulacje DOM po stronie serwera i prawdopodobnie jest to powód, dla którego tu trafiłeś.
Najpierw użyj,
request
aby pobrać stronę do przeanalizowania. Po zakończeniu pobierania obsłuż gocheerio
i rozpocznij manipulację DOM, tak jak przy użyciu jQuery.Przykład roboczy:
Ten przykład wydrukuje w konsoli wszystkie najważniejsze pytania wyświetlane na stronie głównej SO. Właśnie dlatego uwielbiam Node.js i jego społeczność. Nie może być łatwiej :-)
Zainstaluj zależności:
I uruchom (zakładając, że powyższy skrypt znajduje się w pliku
crawler.js
):Kodowanie
Niektóre strony będą zawierać treści w języku innym niż angielski w pewnym kodowaniu i konieczne będzie ich odkodowanie
UTF-8
. Na przykład strona w portugalskim języku brazylijskim (lub innym języku pochodzenia łacińskiego) prawdopodobnie będzie zakodowana wISO-8859-1
(inaczej „latin1”). Kiedy potrzebne jest dekodowanie, mówię,request
aby nie interpretować treści w żaden sposób i zamiast tego używaćiconv-lite
do wykonania zadania.Przykład roboczy:
Przed uruchomieniem zainstaluj zależności:
A potem w końcu:
Poniższe linki
Następnym krokiem będzie skorzystanie z linków. Powiedz, że chcesz wyświetlić listę wszystkich plakatów z każdego górnego pytania w SO. Najpierw musisz wymienić wszystkie najważniejsze pytania (przykład powyżej), a następnie wprowadzić każdy link, analizując stronę każdego pytania, aby uzyskać listę zaangażowanych użytkowników.
Kiedy zaczniesz podążać za linkami, możesz zacząć piekło zwrotne . Aby tego uniknąć, powinieneś użyć obietnic, przyszłości lub cokolwiek innego. Zawsze trzymam asynchronię w pasku narzędzi. Oto pełny przykład robota używającego asynchronizacji:
Przed uruchomieniem:
Uruchom test:
Przykładowe dane wyjściowe:
I to jest podstawa, którą powinieneś wiedzieć, aby zacząć tworzyć własne roboty :-)
Wykorzystane biblioteki
źródło
w 2016 roku sprawy są znacznie łatwiejsze. zainstaluj jquery w node.js za pomocą konsoli:
powiąż go ze zmienną
$
(na przykład - jestem do tego przyzwyczajony) w kodzie node.js:robić coś:
działa również dla gulp, ponieważ jest oparty na node.js.
źródło
var $ = require("jquery"); $.ajax // undefined
(Na razie głosowanie negatywne).npm install jquery
pierwszy?> console.log(require("jquery").toString());
daje mi funkcję fabryczną:function ( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); }
musiałem użyć powyższej odpowiedzi z jsdom: stackoverflow.com/a/4129032/539490Uważam, że odpowiedź na to pytanie brzmi: tak.
https://github.com/tmpvar/jsdom
źródło
npm install jquery --save
# Uwaga WSZYSTKIE DOLNEnpm install jsdom --save
źródło
Moduł jQuery można zainstalować za pomocą:
Przykład:
Referencje jQuery w Node.js **:
źródło
Musisz otworzyć okno za pomocą nowego API JSDOM.
źródło
...
) powinien być .JSDOM („<! DOCTYPE html>”) dla obsługi HTML5?OSTRZEŻENIE
To rozwiązanie, o którym wspomniał Golo Roden, jest nieprawidłowe . Jest to tylko szybka poprawka, aby pomóc ludziom uruchomić ich rzeczywisty kod jQuery za pomocą struktury aplikacji Node, ale nie jest to filozofia Node, ponieważ jQuery nadal działa po stronie klienta, a nie po stronie serwera. Przepraszam za udzielenie złej odpowiedzi.
Możesz także wyrenderować Jade z węzłem i umieścić w nim swój kod jQuery. Oto kod pliku jadeit:
źródło
Mój działający kod to:
i wtedy:
lub jeśli okno jest obecne, to:
źródło
Moduł jsdom jest doskonałym narzędziem. Ale jeśli chcesz ocenić całe strony i zrobić trochę funky po stronie serwera, sugeruję uruchomienie ich we własnym kontekście:
Tak więc rzeczy takie jak
require
/CommonJS
on site nie wysadzą samego procesu węzła.Dokumentację można znaleźć tutaj . Twoje zdrowie!
źródło
Począwszy od jsdom v10, funkcja .env () jest przestarzała. Zrobiłem to jak poniżej po wypróbowaniu wielu rzeczy, które wymagają jquery:
Mam nadzieję, że pomoże to Tobie lub każdemu, kto napotkał tego rodzaju problemy.
źródło
TypeError: JSDOM is not a constructor
$.each
. Właśnie zamieściłem te linie, a potem zrobiłem to tak:$.each(errors, function (ind,error) { res.send(error.msg);console.log(error.msg); });
Mam nadzieję, że to pomaga !!Przede wszystkim zainstaluj
Po zainstalowaniu możesz użyć go jak poniżej
Możesz sprawdzić pełny samouczek, który napisałem tutaj: https://medium.com/fbdevclagos/how-to-use-jquery-on-node-df731bd6abc7
źródło
Żadne z tych rozwiązań nie pomogło mi w mojej aplikacji Electron.
Moje rozwiązanie (obejście):
W twoim
index.js
pliku:W swoich
.js
plikach napisz swoje funkcje jQuery w następujący sposób:źródło
Tak,
jQuery
można go używać zNode.js
.Kroki włączenia jQuery do projektu węzła: -
npm i jquery --save
Uwzględnij jquery w kodachUżywam jquery w projektach node.js cały czas, a konkretnie w projekcie rozszerzenia chrome.
np. https://github.com/fxnoob/gesture-control-chrome-extension/blob/master/src/default_plugins/tab.js
źródło
Nie. Przeniesienie środowiska przeglądarki do węzła będzie dość dużym wysiłkiem.
Innym podejściem, które obecnie badam pod kątem testów jednostkowych, jest stworzenie „próbnej” wersji jQuery, która zapewnia wywołania zwrotne przy każdym wywołaniu selektora.
W ten sposób możesz jednostkowo przetestować wtyczki jQuery bez posiadania DOM. Nadal będziesz musiał przetestować w prawdziwych przeglądarkach, aby sprawdzić, czy Twój kod działa na wolności, ale jeśli odkryjesz specyficzne problemy z przeglądarką, możesz łatwo „wyśmiewać” je w testach jednostkowych.
Pchnę coś na github.com/felixge, gdy będzie gotowe do pokazania.
źródło
Możesz użyć Electron , pozwala on na hybrydowe przeglądarki i nodejs.
Wcześniej próbowałem używać canvas2d w nodejs, ale w końcu się poddałem. Nie jest obsługiwany przez domyślny nodejs i jest zbyt trudny do zainstalowania (wiele wielu ... zależności). Dopóki nie użyję Electron, mogę z łatwością używać całego mojego poprzedniego kodu przeglądarki, nawet WebGL, i przekazać wartość wyniku (np. Wynik obrazu base64 obrazu) do kodu nodejs.
źródło
Nie żebym o tym wiedział. DOM jest sprawą po stronie klienta (jQuery nie analizuje HTML, ale DOM).
Oto niektóre bieżące projekty Node.js:
https://github.com/ry/node/wiki ( https://github.com/nodejs/node )
A djangode SimonW jest całkiem fajny ...
źródło
Alternatywą jest użycie Underscore.js . Powinien dostarczać to, czego mogłeś chcieć po stronie serwera od JQuery.
źródło