Node.jsでjQueryを使用できますか?


574

Node.jsを使用してサーバーサイドでjQueryセレクター/ DOM操作を使用することは可能ですか?


3
疑問:クライアント側で実行できるのに、なぜサーバー側で使用するのですか?
Inanc Gumus 2014

31
おそらく、特定の情報を定期的にスクラップし、その結果をデータベースに保存するWebスクラッパーを作成することをお勧めします。これはクライアント側からは実用的ではありません。
Trevor 2014年

2
また、V8エンジンを使用してブラウザーサーバー側をエミュレートできるphantomjsも確認する必要があります。
ディミトリコプリワ2015年

2
サーバー側での@deeperx DOM操作は、クローラーを作成するときに役立ちます。この回答を参照してください。
Lucio Paiva、2015

はい- この答えを見てください-jQueryセレクターの全機能を利用できるので、cheerioを使用するよりもこちらをお勧めします。
monika mevenkamp

回答:


563

アップデート(18-Jun-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チームがjquerynpm でのパッケージの管理を最終的に引き継ぎました:

npm install jquery

次に:

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


43
そのnpmモジュールでnode.jsからjQuery ajaxを使用することは可能ですか?
ajsie

22
Windowsにはインストールしません(重要な作業がない場合)。その場合、Cheerioモジュールをお勧めします:matthewmueller.github.com/cheerio
Simon East

7
npmをどこで取得するかを示すための+1 :)ほとんどの人は、それが与えられたものであるかのように物事を言及するという悪い癖があります(常識)
Val

12
これはを返しますrequire("...").env is not a function
Banderi

4
@バンデリーは私と同じ、どんな考えですか?エラー:TypeError: require(...).env is not a function
coderInrRain 2017

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ノードパッケージを見たところ、jQueryが昨日あった1年前にnQueryが更新されました... nQueryはもはや開発されていませんか?そしてjQueryはnQueryのようにクライアント側に影響を与えますか?誰かが両方を試したことがありますか?
Logan

2
@Logan nQueryは基本的に単なるjqueryです。違いは、コードがサーバー上で実行され、jqueryコードをブラウザーに配信するのではなく、サーバー上でコードを実行し、接続されたブラウザーに対してdom操作をリモートで実行することです。また、nQueryは実験的なプロジェクトであり、私はバグを修正するためのプルリクエストを受け入れますが、特定の目的またはプロジェクトのために作成されたわけではないため、多くのコミットがありませんでした
Thomas Blobaum

@ThomasBlobaumが私にとってうまくいかない、エラー:, express = Express.createServer();そしてTypeError: Express.createServer is not a function何かアイデア?
coderInrRain 2017

@ThomasBlobaumは、Expressの最新バージョンを取得していないようです。npm install --save expressコマンドプロンプトで試してください。
gilbert-v

55

執筆時点では、維持されているCheerioもあります。

サーバー専用に設計されたコアjQueryの高速で柔軟な無駄のない実装。


2
Cheerioの+1。一方、jsdomは、Windowsで実行するのに本当に苦痛です。
Simon East

1
Cheerioは遅延イベントとajax呼び出しを使用できますか?
ホフマン

6
のような多くのセレクターをサポートしていません:gt(1)
チョービー

1
私の経験では、これが最も効果的です。JSDOMよりもはるかに高速です。
Jason Prawn 2014

1
@ホフマン、私はあなたのためにドキュメントをチェックするために一秒を費やしました。いいえ、違います。CheerioにはDOM関連のメソッドのみがあります。
Denis

39

jsdomを使用して、できるようになりました。examplesディレクトリにあるjqueryの例をご覧ください。


jsdomのjQueryify()の1つの欠点は、ページのすべてのスクリプトを実行することです。
2012年

そして、それは多くの頭痛の種がないWindowsでは機能しません
Jason Goemaat '25年

1
2016年にはjsdomはもう必要ありません-私の回答をご覧ください:stackoverflow.com/a/40656811/3391783
low_rents

34

Cheerioを使用した単純なクローラー

これは、Node.jsで単純なクローラーを作成するための私の公式です。これがサーバー側でDOM操作を行いたい主な理由であり、おそらくここに到達した理由です。

まず、を使用requestして、解析するページをダウンロードします。ダウンロードが完了したら、それを処理しますcheerio jQueryを使用する場合と同様、 DOM操作を開始します。

作業例:

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の各上位の質問からすべてのポスターをリストしたいとします。最初にすべての上位の質問(上記の例)をリストしてから、各リンクを入力し、各質問のページを解析して、関係するユーザーのリストを取得する必要があります。

リンクをたどると、コールバック地獄が始まります。それを回避するには、何らかの約束、先物などを使用する必要があります。私はいつも私のツールベルトで非同期を保ちます。したがって、非同期を使用するクローラーの完全な例を次に示します。

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

node.jsに基づいているため、gulpでも機能します。


どのバージョンのノードを使用していますか?Macでは、ノード6.10.2、jquery 2.2.4 var $ = require("jquery"); $.ajax // undefined (現時点では反対投票)。
AJP

@AJPそしてあなたはあなたがnpm install jquery最初にしたと確信していますか?
low_rents 2017年

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?
ボリス・バーコフ2018

18

これに対する答えは今はイエスだと思います。
https://github.com/tmpvar/jsdom

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

9
jsdomでjQueryを実行するには、さらに多くの作業が必要になると報告して申し訳ありません。シズルは効きます!私は本当にjsdomをできるだけ軽くしたいので、env.jsのような完全なブラウザーエミュレーションを追加することは、現時点ではそれほど優先事項ではありません。
tmpvar

気にしないで、jsdomにバンドルされている変更されたコピーを見つけました。
12

FYIノード-jqueryのはjqueryのの賛成で廃止された
ルスラン・ロペス

1
ReferenceError:ウィンドウが定義されていません
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);
});

これはきちんとした答えです!plsがこれに
賛成

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

Node.js **でのjQueryの参照:


2
私には機能しません... C:\ ... \\ node_modules \ jquery \ dist \ jquery.js:31 throw new Error( "jQuery require a window with a document"); ^エラー:jQueryには、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(window、 " code.jquery.com/jquery.js"、function(){var $ = window。$; $( "body")。prepend( "<h1>タイトル</ h1>") ; console.log($( "h1")。html());});
サンダラヤンK 2016

7

新しいJSDOM APIを使用してウィンドウを取得する必要があります。

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

...HTML5をサポートするには、.JSDOM()を.JSDOM( "<!DOCTYPE html>")にする必要がありますか?
datdinhquoc

2

警告

Golo Rodenが述べたこの解決策は正しくありません。Nodeアプリ構造を使用して実際のjQueryコードを実行できるようにするための簡単な修正ですが、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は引き続きクライアント側で実行されます。したがって、この回答は役に立ちません:-/
Golo Roden 2013年

2
はい、ありがとうございます。私はそれを理解しました。それを読んだ人々を混乱させないように、私は答えでそれを明確にするよう努めます。ゴロを助けてくれてありがとう。
Timbergus 2013年

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、サイト上でのは、ノードプロセス自体を破壊しません。

ここにドキュメントがあります。乾杯!


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
Nathan Hawks

ノード側でjQueryを実行している場合は、最初にnpm installを使用してjqueryとjsdomをインストールします。次に、jqueryセレクターを使用しようとしているファイルに上記の行を追加します。たとえば、私はを使用しました$.each。私はこれらの行を含めて、以下のようにそれを行いました: $.each(errors, function (ind,error) { res.send(error.msg);console.log(error.msg); }); これが役立つことを願っています!!
Plabon Dutta

どういうわけかjsdomはまったくインストールしないことにしました。私はまだnpmを理解していると思います。Thanks @
Nathan Hawks


0

これらのソリューションはどれも、Electron Appで私を助けてくれませんでした。

私の解決策(回避策):

npm install jquery

あなたのindex.jsファイルで:

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

.jsファイルに次のようにjQuery関数を記述します。

jQuery(document).ready(function() {


-1

いいえ。ブラウザ環境をノードに移植するのはかなり大変な作業になります。

私が現在ユニットテストのために調査している別のアプローチは、セレクターが呼び出されるたびにコールバックを提供するjQueryの「モック」バージョンを作成することです。

この方法では、実際にDOMがなくてもjQueryプラグインを単体テストできます。実際のブラウザーでテストして、コードが実際に機能するかどうかを確認する必要がありますが、ブラウザー固有の問題を発見した場合は、単体テストでも簡単に「模擬」できます。

表示する準備ができたら、github.com / felixgeに何かをプッシュします。


私はこのアイデアが好きです...それはとても簡単にできるはずです。
Sudhir Jonathan

-1

Electronを使用できます。これは、browserjsとnodejsのハイブリッドを可能にします。

以前は、nodejsでcanvas2dを使用しようとしましたが、ようやくあきらめました。nodejsのデフォルトではサポートされていないため、インストールするのが困難です(多くの...依存関係)。Electronを使用するまでは、以前のすべてのbrowserjsコード(WebGLを含む)を簡単に使用でき、結果の値(たとえば、結果のbase64画像データ)をnodejsコードに渡すことができます。


-9

私が知っていることではありません。DOMはクライアント側のものです(jQueryはHTMLを解析しませんが、DOMを解析します)。

以下に、現在のNode.jsプロジェクトをいくつか示します。

https://github.com/ry/node/wikihttps://github.com/nodejs/node

SimonWのdjangodeはすごくカッコいい...


できればよかったのに。私はすでにnode.jsプロジェクトにjqueryを含めようとしましたが、もちろんそれは機能しませんでした。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 APIに依存しているため、Node.js(V8 / C ++を使用)は使用できません。
クレセントフレッシュ

2
@Nosrednaあなたがそれを書いたとき、これは本当だったかもしれませんが、それはもはやもう本当ではありません。今すぐ回答を削除することをお勧めします。
キースピンソン2014年

-18

別の方法は、Underscore.jsを使用することです。それはあなたがJQueryからサーバー側に望んでいたかもしれないものを提供するはずです。


10
説明できる?jQueryは、多数のDOM操作/トラバース/フィルタリングAPIを提供します。アンダースコアは、DOMとは何の関係もない一般的なライブラリユーティリティのように見えます。
Peter Lyons

1
ここでも同じですが、これがどのように関連しているかはわかりません。2つは代替ではなく、補数です
Yi Jiang

2
この答えは完全に間違っているわけではありません。jQueryとUnderscoreは重複しています。どちらもforEachなどの機能を提供します。
tuomassalo

8
-1機能は重複していますが、アンダースコアはjQueryの代替ではありません。
サム

2
問題は、DOM操作/セレクターについて尋ねることです。
mikermcneil 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.