Posso usar o jQuery com o Node?js?
é possível usar os selectores de jQuery / manipulação de DOM no lado do servidor usando o nó.js?
18 answers
Update (27-Jun-18): parece que houve uma grande atualização para jsdom
que faz com que a resposta original não funcione mais. Eu encontrei esta resposta que explica como usar jsdom
agora. Copiei o código relevante abaixo.
var jsdom = require("jsdom");
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;
var $ = jQuery = require('jquery')(window);
nota: a resposta original não menciona que terá de instalar o jsdom, bem como usar npm install jsdom
Atualização (final de 2013): a equipe oficial da jQuery finalmente assumiu a gestão da jquery
pacote no npm:
npm install jquery
Então ... :
require("jsdom").env("", function (err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
});
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);
No momento da escrita há também os mantidosCheerio .
Implementação rápida, flexível e lean do núcleo jQuery projetado especificamente para o servidor.
Usando jsdom agora podes. Basta olhar para o seu exemplo jquery no diretório de exemplos.
Um simples rastejante usando Cheerio
Esta é a minha fórmula para fazer um simples rastejador no nó.js. É a principal razão para querer fazer manipulação DOM no lado do servidor e provavelmente é a razão pela qual você chegou aqui.Primeiro, utilizar request
para baixar a página a ser processada. Quando o download estiver completo, manuseie-o para cheerio
e começar a manipulação DOM tal como usar jQuery.
Exemplo de trabalho:
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/');
Este exemplo imprimir para a consola todas as perguntas de Topo que aparecem na página inicial. É por isso que adoro o Node.js e sua comunidade. Não podia ser mais fácil do que isso.
Instalar dependências:
MPN install request cheerio
E executar (assumindo que o programa acima está no ficheiro crawler.js
):
Rastejador de nódulos.js
Codificação
Algumas páginas terão conteúdo não-inglês numa determinada codificação e terá de descodificá-lo para UTF-8
. Por exemplo, uma página em português brasileiro (ou qualquer outra língua de origem latina) provavelmente será codificada em ISO-8859-1
(T. c. p. "latin1"). Quando a descodificação é necessária, eu digo request
para não interpretar o conteúdo de qualquer forma e, em vez disso, usar iconv-lite
para fazer o trabalho.
Exemplo de trabalho:
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/');
Antes de correr, instale dependências:
MPN install request iconv-lite cheerio
E finalmente:
Nó indexacao.js
Após ligações
O próximo passo seria seguir ligações. Digamos que você quer listar todos os cartazes de cada pergunta de topo sobre SO. Você tem que primeiro listar todas as perguntas de topo (exemplo acima) e, em seguida, digitar cada link, analisando a página de cada pergunta para obter a lista de Usuários Envolvidos.Quando você começar a seguir links, um inferno de callback pode começar. Para evitar isso, você deve usar algum tipo de promessas, futuros ou o que quer que. Eu sempre mantenho async no meu cinto de ferramentas. Então, aqui está um exemplo completo de um rastreador usando async:
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);
});
});
});
});
Antes de correr:
MPN instalar pedido async cheerio
Faz um teste:
Rastejador de nódulos.js
Saída da amostra:
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
E esse é o básico que você deve saber para começar a fazer seus próprios rastejantes: -)
Bibliotecas
Em 2016 as coisas são muito mais fáceis. instalar o jquery no nó.JS com a sua consola:
npm install jquery
Ligue-o à variável $
(por exemplo-estou habituado a isso) no seu nó.código js:
var $ = require("jquery");
Faz coisas:
$.ajax({
url: 'gimme_json.php',
dataType: 'json',
method: 'GET',
data: { "now" : true }
});
Também funciona para gulp como é baseado no nó.js.
https://github.com/tmpvar/jsdom
var navigator = { userAgent: "node-js" };
var jQuery = require("./node-jquery").jQueryInit(window, navigator);
O módulo JQuery pode ser instalado usando:
npm install jquery
Exemplo:
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);
});
});
Referências do jQuery no nó.js**:
npm install jquery --save
#Nota Todos os minúsculos
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);
});
O meu código de trabalho é:
npm install jquery
E depois:
global.jQuery = require('jquery');
global.$ = global.jQuery;
Ou se a janela estiver presente, então:
typeof window !== "undefined" ? window : this;
window.jQuery = require('jquery');
window.$ = window.jQuery;
Tens de arranjar a janela usando a nova API do JSDOM.
const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);
Aviso
Esta solução, tal como mencionada por Golo Roden não é correcta. É apenas uma correção rápida para ajudar as pessoas a ter seu código jQuery real funcionando usando uma estrutura de App de nó, mas não é a filosofia de nó porque o jQuery ainda está executando no lado do cliente em vez de no lado do servidor. Desculpa por dar uma resposta errada.
Também podes renderizar Jade com um nó e colocar o teu código de jQuery lá dentro. Aqui está o código do jade. ficheiro:
!!! 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();
});
O Módulo jsdom é uma grande ferramenta. Mas se você quiser avaliar páginas inteiras e fazer algumas coisas estranhas no lado do servidor eu sugiro executá-las em seu próprio contexto:
vm.runInContext
Então coisas como require
/ CommonJS
no local não vai explodir o seu processo de nó em si.
Você pode encontrar a documentação aqui. Saúde!
A partir de jsdom v10,.a função env () está desactualizada. Eu fiz como em baixo depois de tentar muitas coisas para exigir jquery:
var jsdom = require('jsdom');
const { JSDOM } = jsdom;
const { window } = new JSDOM();
const { document } = (new JSDOM('')).window;
global.document = document;
var $ = jQuery = require('jquery')(window);
Outra abordagem, que estou actualmente a investigar para testes de unidade, é criar uma versão "Mock" do jQuery que fornece callbacks sempre que um selector é chamado.
Assim, pode testar os seus plugins jQuery sem ter um DOM. Você ainda terá que testar em navegadores reais para ver se o seu código funciona na natureza, mas se você descobrir problemas específicos do navegador, você pode facilmente "zombar" dos testes da sua unidade também. Vou empurrar qualquer coisa para ...github.com/felixge assim que estiver pronto para aparecer.Pode usar Electrão, permite navegadores híbridos e nodejs.
Antes, tentei usar canvas2d em nodejs, mas finalmente desisti. Não é suportado por padrão nodejs, e muito difícil de instalá-lo (muitos ... dependeces). Até que eu use elétron, eu posso facilmente usar todo o meu código de navegação anterior, até mesmo WebGL, e passar o valor do resultado(eg. result base64 image data) to nodejs code.Aqui está um nó actual.projectos js:
E o djangode do SimonW é muito fixe...Uma alternativa é usar sublinhado.js . Deve fornecer o que você poderia querer do lado servidor de JQuery.