Могу ли я использовать jQuery с Node.js?


574

Можно ли использовать селекторы jQuery / манипулирование DOM на стороне сервера с помощью Node.js?


3
Интересно: зачем использовать на стороне сервера, а вы можете делать это на стороне клиента?
Inanc Gumus

31
Возможно, вы захотите создать веб-утилиту, которая будет регулярно удалять конкретную информацию и сохранять результаты в базе данных? Это не было бы так практично со стороны клиента.
Тревор

2
Вы также должны взглянуть на phantomjs, которые позволяют вам эмулировать серверную часть браузера с движком V8.
Дмитрий Коприва

2
@deeperx DOM манипуляции на стороне сервера могут быть полезны при создании сканера. Смотрите этот ответ .
Лусио Пайва

ДА - взгляните на этот ответ - я предпочитаю это, чем использовать cheerio, так как вы получаете всю мощь селектора jQuery.
Моника Мевенкамп

Ответы:


563

Обновление (27 июня 18) : похоже, что произошло серьезное обновление jsdom, из-за которого оригинальный ответ больше не работает. Я нашел этот ответ, который объясняет, как использовать jsdomсейчас. Я скопировал соответствующий код ниже.

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

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

Примечание. В первоначальном ответе не упоминается, что вам также потребуется установить jsdom, используяnpm install jsdom

Обновление (конец 2013 г.) : Официальная команда jQuery наконец-то взяла на себя управление jqueryпакетом на npm:

npm install jquery

Затем:

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


43
Можно ли использовать jQuery ajax из node.js с этим модулем npm?
Ajsie

22
Не устанавливается на Windows (без значительной работы), в этом случае я бы порекомендовал модуль Cheerio
Simon East,

7
+1 для того, чтобы показать, где можно получить npm :) У большинства людей есть плохая привычка просто упоминать вещи, как будто это должно быть дано (здравый смысл)
Val

12
Это возвращается require("...").env is not a function.
Banderi

4
@ Бандери тоже со мной, есть идеи? ошибка:TypeError: require(...).env is not a function
coderInrRain

58

Да, вы можете, используя созданную мной библиотеку под названием nodeQuery

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 фактически меняет страницу пользователя в реальном времени, поэтому он даже круче, чем можно было ожидать.
Alessioalex

Я искал что-то вроде этого, когда наткнулся здесь ... Я только что посмотрел на пакеты узлов nQuery и jquery, а год назад был обновлен nQuery, где вчера был jquery ... nQuery больше не разрабатывается? и влияет ли jquery на клиентскую сторону, как nQuery? Кто-нибудь пробовал их обоих, может быть?
Логан

2
@Logan nQuery - это просто jquery. разница заключается в том, что код запускается на сервере, и вместо того, чтобы доставлять код jquery в браузер, он запускает код на сервере и удаленно выполняет манипуляции с dom для подключенных браузеров. Также обратите внимание, что nQuery был экспериментальным проектом, и хотя я буду принимать запросы на извлечение для исправления ошибок, он никогда не создавался для какой-либо конкретной цели или проекта, поэтому у него не было много
коммитов

@ThomasBlobaum не работает для меня, ошибка: , express = Express.createServer();а TypeError: Express.createServer is not a functionесть идеи?
coderInrRain

@ThomasBlobaum похоже, что у вас нет последней версии Express. Попробуйте npm install --save expressв командной строке.
Гилберт-V

55

На момент написания статьи также есть поддерживаемый Cheerio .

Быстрая, гибкая и бережная реализация ядра jQuery, разработанного специально для сервера.


2
+1 за Cheerio. JSDOM, с другой стороны, очень больно запускать на Windows.
Саймон Ист

1
Может ли Cheerio использовать отложенные события и вызовы ajax?
Хоффманн

6
не поддерживает много селекторов, таких как:gt(1)
chovy

1
По моему опыту, этот работает лучше всего. Это намного быстрее, чем JSDOM.
Джейсон Кревет

1
@Hoffmann, я потратил секунду, чтобы проверить документы для тебя. Нет. У Cheerio есть только методы, связанные с DOM.
Денис

39

Используя jsdom, вы теперь можете. Просто посмотрите на их пример jquery в каталоге примеров.


одна из минусов jQueryify () - это то, что он запускает все скрипты страницы.
drewish

и это не работает на Windows без большого количества головной боли
Джейсон Гоема

1
в 2016 году вам больше не нужен jsdom - см. мой ответ: stackoverflow.com/a/40656811/3391783
low_rents

34

Простой сканер, использующий Cheerio

Это моя формула сделать простой сканер в Node.js. Это основная причина желания манипулировать DOM на стороне сервера и, возможно, именно поэтому вы попали сюда.

Во-первых, используйте requestдля загрузки страницы для анализа. Когда загрузка будет завершена, обработайте ее cheerioи начните манипулирование DOM так же, как с помощью jQuery.

Рабочий пример:

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

Этот пример выведет на консоль все основные вопросы, отображаемые на домашней странице SO. Вот почему я люблю Node.js и его сообщество. Это не могло быть легче, чем это :-)

Установить зависимости:

npm установить запрос cheerio

И запустить (при условии, что приведенный выше скрипт находится в файле crawler.js):

узел crawler.js


кодирование

Некоторые страницы будут содержать неанглийский контент в определенной кодировке, и вам нужно будет его декодировать UTF-8. Например, страница на бразильском португальском языке (или любом другом языке латинского происхождения), вероятно, будет закодирована в ISO-8859-1(иначе, как «latin1»). Когда требуется декодирование, я советую requestне интерпретировать содержимое, а использовать его iconv-liteдля выполнения работы.

Рабочий пример:

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

Перед запуском установите зависимости:

npm установить запрос iconv-lite cheerio

И вот наконец:

узел crawler.js


Следующие ссылки

Следующим шагом будет переход по ссылкам. Скажем, вы хотите перечислить все постеры с каждого главного вопроса на SO. Вы должны сначала перечислить все главные вопросы (пример выше), а затем ввести каждую ссылку, анализируя страницу каждого вопроса, чтобы получить список вовлеченных пользователей.

Когда вы начинаете переходить по ссылкам, может начаться ад обратного вызова . Чтобы избежать этого, вы должны использовать какие-то обещания, фьючерсы или что-то еще. Я всегда держу асинхронный в своем инструментальном поясе. Итак, вот полный пример сканера, использующего 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);
            });
        });
    });
});

Перед запуском:

npm установить запрос async cheerio

Запустите тест:

узел crawler.js

Пример вывода:

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

И это основное, что вы должны знать, чтобы начать создавать свои собственные сканеры :-)


Используемые библиотеки


22

в 2016 году все намного проще. установите jquery в node.js с вашей консоли:

npm install jquery

свяжите его с переменной $(например, я привык к ней) в вашем коде node.js:

var $ = require("jquery");

делать вещи:

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

также работает для gulp, так как он основан на node.js.


Какую версию узла вы используете? На Mac, Node 6.10.2, jquery 2.2.4, var $ = require("jquery"); $.ajax // undefined (на данный момент не голосуем ).
AJP

@AJP, а ты уверен, что сделал npm install jqueryпервым?
low_rents

1
Да. > console.log(require("jquery").toString());дает мне фабричную функцию: function ( w ) { if ( !w.document ) { throw new Error( "jQuery requires a window with a document" ); } return factory( w ); } я должен был использовать ответ выше с jsdom: stackoverflow.com/a/4129032/539490
AJP

@ AJP хорошо, это странно.
low_rents

Я получаю точно такую ​​же заводскую функцию, как @AJP. Какую версию jquery вы использовали, @low_rents?
Борис Бурков

18

Я считаю, что ответ на этот вопрос теперь да.
https://github.com/tmpvar/jsdom

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

9
Мне жаль сообщать, что для запуска jQuery на jsdom потребуется больше работы. Sizzle однако работает! Я действительно хочу, чтобы jsdom был как можно более легким, поэтому добавление полной эмуляции браузера, такой как env.js, на самом деле не является приоритетом.
tmpvar

не берите в голову, я нашел измененную копию, которая связана с JSDOM.
drewish

FYI node-jquery устарела в пользу jquery
Руслан Лопес,

1
ReferenceError: окно не определено
Бонн

17

npm install jquery --save #note ВСЕ 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);
});

это аккуратный ответ! Просьба поддержать это
datdinhquoc

8

Модуль jQuery можно установить с помощью:

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

Ссылки jQuery в Node.js **:


2
У меня не работает ... C: \ ... \\ node_modules \ jquery \ dist \ jquery.js: 31 выбросить новую ошибку ("jQuery требует окно с документом"); ^ Ошибка: jQuery требует окно с документом в module.exports (C: \ ... \ WebContent \ resources \ js \ node_modules \ jquery \ dist \ jquery.js: 31: 12)
Хосе Мануэль Гомес Альварес

var jsdom = require ("jsdom"); var window = jsdom.jsdom (). defaultView; jsdom.jQueryify (window, " code.jquery.com/jquery.js ", function () {var $ = window. $; $ ("body"). prepend ("<h1> The title </ h1>") ; console.log ($ ("h1"). html ());});
СУНДАРРАДЖАН К

7

Вы должны получить окно, используя новый JSDOM API.

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

.JSDOM ( ...) должен быть .JSDOM ("<! DOCTYPE html>") для поддержки HTML5?
datdinhquoc

2

ПРЕДУПРЕЖДЕНИЕ

Это решение, как упоминал Голо Роден , не является правильным . Это просто быстрое решение, помогающее людям запускать свой реальный код jQuery с использованием структуры приложения Node, но это не философия Node, поскольку jQuery все еще работает на стороне клиента, а не на стороне сервера. Я прошу прощения за неправильный ответ.


Вы также можете визуализировать Jade с помощью узла и поместить свой код jQuery внутрь. Вот код файла Jade:

!!! 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
Проголосовал, потому что в вопросе прямо сказано, что речь идет о jQuery на стороне сервера. Просто встраивая jQuery в jade-файл, jQuery по-прежнему запускается на стороне клиента. Следовательно, этот ответ не поможет: - /
Голо Роден

2
Хорошо, большое спасибо. Я понял это. Я постараюсь уточнить это в ответе, чтобы не путать людей, которые это читают. Еще раз спасибо за вашу помощь Golo.
Тимбергус

2
Пожалуйста :-). И не берите в голову: мы все делаем наши ошибки, так что не волнуйтесь :-)
Golo Roden

2

Мой рабочий код:

npm install jquery

а потом:

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

или если окно присутствует, то:

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

1

Модуль jsdom - отличный инструмент. Но если вы хотите оценить целые страницы и сделать что-нибудь интересное на их стороне сервера, я предлагаю запустить их в их собственном контексте:

vm.runInContext

Такие вещи, как require/CommonJS на сайте, не повредят самому процессу Node.

Вы можете найти документацию здесь . Ура!


1

Начиная с jsdom v10, функция .env () устарела. Я сделал это, как показано ниже, после того, как многие вещи требовали 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);

Надеюсь, что это поможет вам или любому, кто сталкивался с такими проблемами.


TypeError: JSDOM is not a constructor
Натан Хокс

Если вы используете jQuery на стороне Node, сначала установите jquery и jsdom, используя npm install. Затем добавьте вышеуказанные строки в файл, в котором вы пытаетесь использовать селектор jquery. Например, я использовал a $.each. Я просто включил эти строки, а затем сделал это, как показано ниже: $.each(errors, function (ind,error) { res.send(error.msg);console.log(error.msg); }); Надеюсь, это поможет!
Plabon Dutta

Каким-то образом JSDOM решили вообще не устанавливать. Я предполагаю, что я все еще вычисляю npm. Спасибо @
Натан Хокс

1

Прежде всего установите его

npm install jquery -S

После установки вы можете использовать его, как показано ниже

import $ from 'jquery';
window.jQuery = window.$ = $;
$(selector).hide();

Вы можете ознакомиться с полным руководством, которое я написал здесь: https://medium.com/fbdevclagos/how-to-use-jquery-on-node-df731bd6abc7


0

Ни одно из этих решений не помогло мне в моем приложении «Электрон».

Мое решение (обходной путь):

npm install jquery

В вашем index.jsфайле:

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

В ваших .jsфайлах напишите ваши функции jQuery следующим образом:

jQuery(document).ready(function() {

0

Да, jQueryможно использовать с Node.js.

Шаги для включения jQuery в проект узла: -

npm i jquery --save Включить jquery в коды

import jQuery from 'jquery';

const $ = jQuery;

Я использую jquery в проектах node.js все время, особенно в проекте расширения chrome.

например, https://github.com/fxnoob/gesture-control-chrome-extension/blob/master/src/default_plugins/tab.js


-1

Нет. Это будет довольно большая попытка перенести среду браузера на узел.

Другой подход, который я сейчас изучаю для модульного тестирования, заключается в создании «пробной» версии jQuery, которая обеспечивает обратные вызовы при каждом вызове селектора.

Таким образом, вы можете тестировать свои плагины jQuery, не имея DOM. Вам все равно придется тестировать в реальных браузерах, чтобы увидеть, работает ли ваш код в открытом режиме, но если вы обнаружите специфичные для браузера проблемы, вы также можете легко «насмехаться» над ними в своих модульных тестах.

Я добавлю что-нибудь на github.com/felixge, как только он будет готов к показу.


Мне нравится эта идея ... это должно быть довольно легко сделать.
Судхир Джонатан

-1

Вы можете использовать Electron , он допускает гибридные browserjs и nodejs.

Раньше я пытался использовать canvas2d в nodejs, но в конце концов я сдался. Он не поддерживается по умолчанию для nodejs, и его слишком сложно установить (много-много ... зависимостей). Пока я не использую Electron, я могу легко использовать весь свой предыдущий код browserjs, даже WebGL, и передавать значение результата (например, данные изображения base64) в код nodejs.


-9

Не то, что я знаю из. DOM - это вещь на стороне клиента (jQuery анализирует не HTML, а DOM).

Вот некоторые текущие проекты Node.js:

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

И Djangode SimonW чертовски круто ...


Я хотел бы, чтобы это было возможно. Я уже пытался включить jquery в проект node.js и, конечно, это не сработало. JQuery основан на документе / окне. Rhino способен запускать серверную часть jQuery: ejohn.org/blog/bringing-the-browser-to-the-server Я собираюсь искать другие парсеры. Может быть, есть тот, который не зависит от браузера.
Джон

@John: единственная причина, по которой jQuery может работать на Rhino, заключается в этом проекте: github.com/jeresig/env-js/blob/master/src/env.js. Он моделирует небольшую часть DOM и среды выполнения JavaScript. Он основан на Java apis, поэтому Node.js не используется (который использует V8 / C ++).
Crescent Fresh

2
@Nosredna Хотя, возможно, это было правдой, когда вы это написали, это явно уже не так. Я предлагаю вам удалить свой ответ сейчас.
Кит Пинсон

-18

Альтернативой является использование Underscore.js . Он должен предоставить то, что вы, возможно, хотели на стороне сервера от JQuery.


10
Вы можете объяснить? jQuery предоставляет множество API для манипулирования, обхода и фильтрации DOM. Подчеркивание выглядит как общие библиотечные утилиты, не имеющие ничего общего с DOM.
Питер Лайонс

1
То же самое и здесь, я не вижу, насколько это актуально, эти два дополнения, а не альтернативы
Yi Jiang

2
Этот ответ не совсем неверен. jQuery и Underscore перекрываются: они оба предоставляют такие функции, как forEach.
Туомассало

8
-1 Они имеют перекрывающуюся функциональность, но Underscore не является заменой jQuery.
Сэм

2
Вопрос в том, что касается манипуляции с DOM / селекторов.
mikermcneil
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.