Node.js와 함께 jQuery를 사용할 수 있습니까?


574

Node.js를 사용하여 서버 측에서 jQuery 선택기 / DOM 조작을 사용할 수 있습니까?


3
궁금한 점이 있습니다. 왜 클라이언트 측에서 서버 측에서 사용할 수 있습니까?
Inanc Gumus

31
아마도 특정 정보를 정기적으로 스크랩하고 결과를 데이터베이스에 저장하는 웹 스크레이퍼를 만들고 싶습니까? 이것은 클라이언트 측에서 실용적이지 않습니다.
Trevor

2
V8 엔진을 사용하여 브라우저 서버 측을 에뮬레이트 할 수있는 phantomjs도 살펴 봐야합니다.
Dimitri Kopriwa

2
서버 측에서 @deeperx DOM 조작은 크롤러를 만들 때 유용 할 수 있습니다. 이 답변을 참조하십시오 .
Lucio Paiva

예- 이 답변을 살펴보십시오 .jQuery 선택기의 모든 기능을 활용할 수 있기 때문에 cheerio를 사용하는 것보다 이것을 선호합니다.
monika mevenkamp

답변:


563

업데이트 (27-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
@Banderi 나랑 같은 생각이야? 오류 :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 노드 패키지를 보았으며 jQuery가 어제 있었던 1 년 전에 nQuery가 업데이트되었습니다 ... nQuery가 더 이상 개발되지 않습니까? nQuery와 마찬가지로 jquery는 클라이언트 측에 영향을 줍니까? 아무도 그들 모두를 시도 했습니까?
로건

2
@Logan nQuery는 기본적으로 jquery입니다. 차이점은 코드는 서버에서 실행되며 jquery 코드를 브라우저로 전달하는 대신 서버에서 코드를 실행하고 연결된 브라우저에 대한 원격 조작을 원격으로 실행한다는 것입니다. 또한 nQuery는 실험적인 프로젝트였으며 버그를 수정하기위한 풀 요청을 수락하지만 특정 목적이나 프로젝트를 위해 생성 된 적이 없으므로 많은 커밋이 없었습니다.
Thomas Blobaum

@ThomasBlobaum 나를 위해 작동하지 않습니다, 오류 : , express = Express.createServer();그리고 TypeError: Express.createServer is not a function어떤 아이디어?
coderInrRain

@ThomasBlobaum에 최신 버전의 Express가없는 것 같습니다. npm install --save express명령 프롬프트에서 시도하십시오 .
gilbert-v

55

글을 쓰는 시점에 유지되는 Cheerio도 있습니다.

서버를 위해 특별히 설계된 핵심 jQuery를 빠르고 유연하며 간결하게 구현합니다.


2
Cheerio의 경우 +1 반면에 jsdom은 Windows에서 실행하기가 정말 어렵습니다.
Simon East

1
Cheerio는 지연된 이벤트 및 Ajax 호출을 사용할 수 있습니까?
호프만

6
:gt(1)
chovy

1
내 경험상이 것이 가장 효과적입니다. JSDOM보다 훨씬 빠릅니다.
Jason Prawn

1
@Hoffmann, 나는 당신을 위해 문서를 확인하는 데 잠시 시간을 보냈습니다. 아니 그렇지 않아. Cheerio에는 DOM 관련 방법 만 있습니다.
Denis


34

Cheerio를 사용하는 간단한 크롤러

이것은 Node.js에서 간단한 크롤러를 만드는 공식입니다. 서버 측에서 DOM 조작을 수행하려는 주된 이유이며 아마도 여기에있는 이유 일 것입니다.

먼저 request구문 분석 할 페이지를 다운로드하는 데 사용하십시오. 다운로드가 완료되면 cheeriojQuery를 사용하는 것처럼 처리하고 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에 대한 각 주요 질문의 모든 포스터를 나열하고 싶다고 가정 해보십시오. 먼저 모든 주요 질문 (위의 예)을 나열한 다음 각 링크를 입력하여 각 질문의 페이지를 구문 분석하여 관련 사용자 목록을 가져와야합니다.

링크를 따라 가면 콜백 지옥 이 시작될 수 있습니다. 이를 피하려면 어떤 약속, 선물 등을 사용해야합니다. 나는 항상 툴 벨트에서 비동기 상태를 유지 합니다. 다음은 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 설치 요청 비동기 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에서는 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와 정확히 동일한 팩토리 기능을 얻습니다. @low_rents 어떤 버전의 jquery를 사용 했습니까?
Boris Burkov

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과 함께 제공되는 수정 된 사본을 발견했다.
drewish 2012

참고 노드 JQuery와 JQuery와에 찬성 지금은 사용되지 않습니다
루슬란 로페즈

1
ReferenceError : 창이 정의되지 않았습니다
Bonn

17

npm install jquery --save #note 모두 소문자

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

Node.js에서 jQuery에 대한 참조 ** :


2
나를 위해 작동하지 않습니다 ... C : \ ... \\ node_modules \ jquery \ dist \ jquery.js : 31 throw new Error ( "jQuery에는 창이있는 창이 필요합니다"); ^ 오류 : 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 (창, " code.jquery.com/jquery.js ", function () {var $ = window. $; $ ( "body"). prepend ( "<h1> 제목 </ h1>") console.log ($ ( "h1"). html ());});
SUNDARRAJAN K

7

새로운 JSDOM API를 사용하여 창을 가져와야합니다.

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

...HTML5 지원을 위해 .JSDOM ( )은 .JSDOM ( "<! DOCTYPE html>")이어야합니까?
datdinhquoc

2

경고

같은 언급이 솔루션, GOLO 로덴은 하지 않습니다 올바른 . 사람들이 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

2
고마워요 이해했습니다. 나는 그것을 읽는 사람들을 혼동하지 않기 위해 답을 명확히하려고 노력할 것입니다. 당신의 도움 Golo에 다시 한 번 감사드립니다.
Timbergus

2
천만에요 :-). 그리고 결코 마음 : 우리 모두는 우리의 실수를, 그래서 걱정을하지 :-)
GOLO 로덴에게

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 selector를 사용하려는 파일에 위의 행을 추가하십시오. 예를 들어, 나는을 사용했습니다 $.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

아니요. 브라우저 환경을 노드로 이식하는 데 큰 노력이 필요합니다.

현재 단위 테스트를 위해 조사하고있는 또 다른 방법은 선택기가 호출 될 때마다 콜백을 제공하는 "Mock"버전의 jQuery를 만드는 것입니다.

이렇게하면 실제로 DOM이 없어도 jQuery 플러그인을 단위 테스트 할 수 있습니다. 코드가 제대로 작동하는지 확인하려면 실제 브라우저에서 테스트해야하지만 브라우저 관련 문제를 발견하면 단위 테스트에서 쉽게 "모의"할 수 있습니다.

보여줄 준비가되면 github.com/felixge에 뭔가를 넣겠습니다.


나는이 아이디어를 좋아한다. 아주 쉬운 일이다.
Sudhir Jonathan

-1

Electron 을 사용할 수 있으며 하이브리드 브라우저 및 노드를 허용합니다.

이전에는 nodejs에서 canvas2d를 사용하려고했지만 마침내 포기했습니다. nodejs 기본적으로 지원되지 않으며 설치하기가 너무 어렵습니다 (많은 ... 종속 자). Electron을 사용할 때까지 이전의 모든 browserjs 코드, 심지어 WebGL을 쉽게 사용하고 결과 값 (예 : 결과 base64 이미지 데이터)을 nodejs 코드에 전달할 수 있습니다.


-9

내가 아는 한에서는 아니다. DOM은 클라이언트 측입니다 (jQuery는 HTML을 파싱하지 않지만 DOM).

다음은 현재 Node.js 프로젝트입니다.

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

그리고 SimonW의 장고 는 정말 멋지다 ...


가능했으면 좋겠다. 이미 node.js 프로젝트에 jquery를 포함하려고 시도했지만 물론 작동하지 않았습니다. jQuery는 문서 / 창을 기반으로합니다. Rhino는 jQuery 서버 측을 실행할 수 있습니다 : ejohn.org/blog/bringing-the-browser-to-the-server 더 많은 파서를 찾아 볼 것입니다. 브라우저에 의존하지 않는 것이있을 수 있습니다.
John

@John : jQuery가 Rhino에서 실행될 수있는 유일한 이유는이 프로젝트 때문입니다. github.com/jeresig/env-js/blob/master/src/env.js DOM과 JavaScript 런타임의 작은 부분을 시뮬레이션합니다. Java api에 의존하므로 Node.js (V8 / C ++를 사용)에 대한 이동이 필요하지 않습니다.
초승달 신선한

2
@Nosredna 당신이 그것을 썼을 때 이것이 사실 일지 모르지만, 그것은 더 이상 사실이 아닙니다. 지금 답변을 삭제하시기 바랍니다.
Keith Pinson

-18

대안은 Underscore.js 를 사용하는 것입니다 . JQuery에서 서버 측에 원하는 것을 제공해야합니다.


10
설명 할 수 있습니까? jQuery는 수많은 DOM 조작 / 탐색 / 필터링 API를 제공합니다. 밑줄은 DOM과 관련이없는 일반 라이브러리 유틸리티처럼 보입니다.
Peter Lyons

1
여기에서도 마찬가지입니다. 이것이 두 가지 대안이 아닌 보완적인 관계인지는 알 수 없습니다.
Yi Jiang

2
이 답변은 완전히 틀리지 않습니다. jQuery와 Underscore는 겹칩니다. 둘 다 forEach와 같은 기능을 제공합니다.
tuomassalo

8
-1 기능이 겹치지 만 Underscore는 jQuery를 대체하지 않습니다.
Sam

2
문제는 DOM 조작 / 선택기에 대해 묻는 것입니다.
mikermcneil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.