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

549

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

  • 3
    Я задаюсь вопросом: зачем использовать на стороне сервера, в то время как вы можете сделать это на стороне клиента?
  • 24
    Возможно, вы захотите создать веб-утилиту, которая будет регулярно удалять конкретную информацию и сохранять результаты в базе данных? Это не было бы так практично со стороны клиента.
Показать ещё 2 комментария

19 ответов

523

Обновление (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);
});

  • 40
    Можно ли использовать jQuery ajax из node.js с этим модулем npm?
  • 21
    Не устанавливается в Windows (без значительной работы), в этом случае я бы порекомендовал модуль Cheerio : matthewmueller.github.com/cheerio
Показать ещё 14 комментариев
51

Да, вы можете, используя созданную мной библиотеку, называемую nodeQuery https://github.com/tblobaum/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);
  • 18
    Обратите внимание, что nodeQuery фактически меняет страницу пользователя в реальном времени, поэтому он даже круче, чем можно было ожидать.
  • 0
    Я искал что-то вроде этого, когда наткнулся здесь ... Я только что посмотрел на пакеты узлов nQuery и jquery, а год назад был обновлен nQuery, где вчера был jquery ... nQuery больше не разрабатывается? и влияет ли jquery на клиентскую сторону, как nQuery? Кто-нибудь пробовал их обоих, может быть?
Показать ещё 3 комментария
48

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

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

  • 2
    +1 за Cheerio. JSDOM, с другой стороны, очень больно запускать на Windows.
  • 0
    Может ли Cheerio использовать отложенные события и вызовы ajax?
Показать ещё 4 комментария
38

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

  • 0
    одна из минусов jQueryify () - это то, что он запускает все скрипты страницы.
  • 0
    и это не работает на Windows без большого количества головной боли
Показать ещё 1 комментарий
30

Простой сканер с использованием 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

И запустите (если script выше в файле crawler.js):

node crawler.js


Кодировка

Некоторые страницы будут иметь не-английский контент в определенной кодировке, и вам нужно будет декодировать его до UTF-8. Например, страница на бразильском португальском языке (или любой другой язык латинского происхождения), скорее всего, будет закодирована в ISO-8859-1 (a.k.a. "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

И наконец:

node crawler.js


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

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

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

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

node 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

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


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

18

в 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.

  • 0
    Какую версию узла вы используете? В Mac, Node 6.10.2, jquery 2.2.4, var $ = require("jquery"); $.ajax // undefined (на данный момент не var $ = require("jquery"); $.ajax // undefined ).
  • 0
    @AJP, а ты уверен, что сначала npm install jquery ?
Показать ещё 4 комментария
17

Я считаю, что ответ на этот вопрос теперь да. 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, на самом деле не является приоритетом.
  • 0
    @tmpvar, не могли бы вы рассказать больше о том, как заставить работу работать?
Показать ещё 2 комментария
9

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);
});
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)
  • 0
    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 ());});
4

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

const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM('...');
var $ = require("jquery")(window);
  • 1
    Благодарю. из всех 17 ответов это единственный правильный ответ.
3

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

npm install jquery

а затем:

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

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

typeof window !== "undefined" ? window : this;
window.jQuery   = require('jquery');
window.$        = window.jQuery;
  • 0
    работает на электроне ^ 2.0.0 :)
2

Внимание

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


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

!!! 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();
      });
  • 3
    Проголосовал, потому что в вопросе прямо сказано, что речь идет о jQuery на стороне сервера. Просто встраивая jQuery в jade-файл, jQuery по-прежнему запускается на стороне клиента. Следовательно, этот ответ не помогает: - /
  • 2
    Хорошо, большое спасибо. Я понял это. Я постараюсь уточнить это в ответе, чтобы не путать людей, которые это читают. Еще раз спасибо за вашу помощь Golo.
Показать ещё 1 комментарий
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);

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

1

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

vm.runInContext

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

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

0

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

npm install jquery -S

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

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

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

0

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

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

0

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

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

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

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

  • 0
    Мне нравится эта идея ... это должно быть довольно легко сделать.
-11

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

Вот несколько текущих проектов Node.js:

http://wiki.github.com/ry/node

И SimonW djangode довольно чертовски круто...

  • 0
    Я хотел бы, чтобы это было возможно. Я уже пытался включить jquery в проект node.js и, конечно, это не сработало. JQuery основан на документе / окне. Rhino способен запускать серверную часть jQuery: ejohn.org/blog/bringing-the-browser-to-the-server Я собираюсь искать другие парсеры. Может быть, есть тот, который не зависит от браузера.
  • 1
    Вы пытались спросить в группе Google? groups.google.com/group/envjs
Показать ещё 2 комментария
-17

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню