是否可以在服务器端使用Node.js使用jQuery选择器/ DOM操作?
#1 楼
更新(2018年6月27日):似乎对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);
注意:原始答案没有提及您还需要使用
npm install jsdom
安装jsdom 更新(2013年末):官方jQuery团队最终在npm上接管了
jquery
软件包的管理:npm install jquery
然后:
require("jsdom").env("", function (err, window) {
if (err) {
console.error(err);
return;
}
var $ = require("jquery")(window);
});
评论
是否可以在该npm模块中使用来自node.js的jQuery ajax?
– ajsie
2011年3月1日21:02
不会在Windows上安装(无需大量工作),在这种情况下,我建议使用Cheerio模块:matthewmueller.github.com/cheerio
–西蒙东
13年3月31日在7:02
+1表示从哪里获取npm :)大多数人都有一个坏习惯,就是仅仅提一些东西,就像应该给它一样(常识)
–Val
13年4月11日在13:41
这返回require(“ ...”)。env不是函数。
–班德里
17年5月28日在2:41
@Banderi和我一样,有什么想法吗?错误:TypeError:require(...)。env不是函数
– zukijuki
17年8月8日在10:58
#2 楼
是的,可以使用我创建的名为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);
评论
请注意,nodeQuery实际上实际上是在实时更改用户页面,因此它甚至比人们期望的还要酷。
– alessioalex
2011年11月4日在20:01
当我偶然发现这里时,我正在搜索类似的内容...我刚刚看过nQuery和jquery节点程序包,并且nQuery是在一年前更新的,昨天的jquery是... nQuery不再开发了吗? jQuery是否会像nQuery一样影响客户端?有人尝试过它们吗?
–登录
2012年12月2日在8:23
@Logan nQuery基本上只是jquery。区别在于代码在服务器上运行,而不是将jquery代码传递到浏览器,而是在服务器上运行代码,并远程对连接的浏览器执行dom操作。还要注意,nQuery是一个实验项目,尽管我将接受拉取请求以修复错误,但它从未为任何特定目的或项目而创建,因此它没有很多提交
–托马斯·布拉鲍姆(Thomas Blobaum)
2012年12月6日15:13
@ThomasBlobaum对我不起作用,错误:,express = Express.createServer();和TypeError:Express.createServer不是一个函数吗?
– zukijuki
17年8月8日在11:02
@ThomasBlobaum似乎您没有最新版本的Express。在命令提示符下尝试npm install --save express。
– Gilbert-v
19年5月31日在9:52
#3 楼
在撰写本文时,还维护了Cheerio。快速,灵活和精益的jQuery核心实现是专门为服务器设计的。
/>
评论
+1为Cheerio。另一方面,jsdom很难在Windows上运行。
–西蒙东
13年3月31日在7:01
Cheerio可以使用延迟事件和Ajax调用吗?
–霍夫曼
2014年2月21日在14:16
不支持很多选择器,例如:gt(1)
–碎肉
2014年5月24日21:44
以我的经验,这是最好的。它比JSDOM快很多。
–杰森·普兰(Jason Prawn)
2014年9月17日在11:51
@霍夫曼,我花了一秒钟时间为您检查文档。不,不是的。 Cheerio仅具有与DOM相关的方法。
–丹尼斯
15年11月22日在18:41
#4 楼
使用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 install request cheerio
并运行(假设上面的脚本在文件
crawler.js
中):node 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安装请求图标v-lite cheerio
然后是最后:
node 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安装请求异步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
这就是开始制作自己的搜寻器时应该了解的基本知识:-)
使用的库
请求
iconv-lite
cheerio
异步
#5 楼
在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上,节点6.10.2,jquery 2.2.4,var $ = require(“ jquery”); $ .ajax //未定义(暂时投票)。
– AJP
17年5月9日在14:18
@AJP,您确定先npm先安装了jquery吗?
–low_rents
17年5月10日在7:41
是。 > console.log(require(“ jquery”)。toString());给了我工厂函数:function(w){if(!w.document){throw new Error(“ jQuery需要一个带有文档的窗口”); }返回工厂(w);我必须对jsdom使用以上答案:stackoverflow.com/a/4129032/539490
– AJP
17年5月10日在9:35
@AJP好的,这很奇怪。
–low_rents
17年5月10日在12:04
我得到与@AJP完全相同的工厂函数。您使用了哪个版本的jquery,@ low_rents?
– Boris Burkov
18年2月15日在0:55
#6 楼
我相信现在的答案是肯定的.https://github.com/tmpvar/jsdomvar navigator = { userAgent: "node-js" };
var jQuery = require("./node-jquery").jQueryInit(window, navigator);
评论
很遗憾地报告,要使jQuery在jsdom上运行还需要更多的工作。但是嘶嘶声确实起作用!我真的想尽可能减少jsdom的负担,因此,此时添加诸如env.js之类的完整浏览器仿真并不是真正的优先事项。
– tmpvar
2010年5月4日14:34
没关系,我发现与jsdom捆绑在一起的修改后的副本。
–酒
2012年2月27日在21:18
现在不赞成使用FYI node-jquery,而推荐使用jquery
–RuslanLópez
18年4月25日在6:52
ReferenceError:窗口未定义
–波恩
19年8月7日在10:39
#7 楼
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);
});
#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的引用**:
http://quaintous.com/2015/07/31/jqery-node-mystery/
http://www.hacksparrow.com/jquery -with-node-js.html
评论
对我不起作用... C:\ ... \\ node_modules \ jquery \ dist \ jquery.js:31抛出新错误(“ jQuery需要带有文档的窗口”); ^错误:jQuery要求一个带有在module.exports(C:\ ... \ WebContent \ resources \ js \ node_modules \ jquery \ dist \ jquery.js:31:12)上的文档的窗口
–乔斯·曼努埃尔·戈麦斯·阿尔瓦雷斯
16-10-20在17:59
var jsdom = require(“ jsdom”); var window = jsdom.jsdom()。defaultView; jsdom.jQueryify(窗口,“ code.jquery.com/jquery.js”,函数(){var $ = window。$; $(“ body”)。prepend(“
标题
”) ; console.log($(“ h1”)。html());});– SUNDARRAJAN K
16-10-20在18:06
#9 楼
您必须使用新的JSDOM API来获取窗口。const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);
评论
.JSDOM(...)应该为HTML5支持的.JSDOM(“ <!DOCTYPE html>”)吗?
– datdinhquoc
1月29日3:10
#10 楼
警告Golo Roden提到的此解决方案是不正确的。这只是一个快速的解决方案,可以帮助人们使用Node应用程序结构运行其实际的jQuery代码,但这不是Node原理,因为jQuery仍在客户端而不是服务器端运行。很抱歉给您一个错误的答案。
您还可以使用node渲染Jade并将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();
});
评论
拒绝投票是因为该问题明确表明它与服务器端的jQuery有关。通过简单地将jQuery嵌入到玉文件中,jQuery仍在客户端上运行。因此,此答案无济于事:-/
– Golo Roden
13年5月31日晚上8:24
好的,非常感谢。我明白了我将尝试在答案中加以澄清,以免使阅读它的人感到困惑。再次感谢您对Golo的帮助。
– Timbergus
13年5月31日在10:15
别客气 :-)。没关系:我们都会犯错,所以不用担心:-)
– Golo Roden
13年5月31日在10:49
#11 楼
我的工作代码是:npm install jquery
然后:
global.jQuery = require('jquery');
global.$ = global.jQuery;
或者如果存在窗口,则:
typeof window !== "undefined" ? window : this;
window.jQuery = require('jquery');
window.$ = window.jQuery;
#12 楼
首先安装它npm install jquery -S
安装后,可以按以下方式使用它
import $ from 'jquery';
window.jQuery = window.$ = $;
$(selector).hide();
您可以查看我在这里写的完整教程:https://medium.com/fbdevclagos/how-to-use-jquery-on-node-df731bd6abc7
#13 楼
jsdom模块是一个很棒的工具。但是,如果您要评估整个页面并在服务器端对它们进行一些时髦的处理,建议您在各自的上下文中运行它们:vm.runInContext
因此,诸如
require
/ CommonJS
该站点不会破坏Node进程本身。您可以在此处找到文档。干杯!
#14 楼
从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不是构造函数
–内森·霍克斯(Nathan Hawks)
19/12/30在20:37
如果您在Node端运行jQuery,请首先使用npm install安装jquery和jsdom。然后,在尝试使用jquery选择器的文件中添加以上行。例如,我使用了$ .each。我只包含了这些行,然后按如下所示进行操作:$ .each(错误,函数(ind,error){res.send(error.msg); console.log(error.msg);});希望这可以帮助 !!
– Plabon Dutta
19/12/31在11:10
jsdom决定以某种方式根本不安装。我想我仍然在计算npm。谢谢@
–内森·霍克斯(Nathan Hawks)
19/12/31在15:35
#15 楼
这些解决方案都没有对我的电子应用程序有所帮助。我的解决方案(变通办法):
npm install jquery
在您的
index.js
文件中:var jQuery = $ = require('jquery');
在您的
.js
文件中,以这种方式编写jQuery函数:jQuery(document).ready(function() {
#16 楼
是的,jQuery
可以与Node.js
一起使用。 在节点项目中包含jQuery的步骤:-
npm i jquery --save
在代码中包含jQuery
import jQuery from 'jquery';
const $ = jQuery;
我确实一直在node.js项目中使用jquery,尤其是在chrome扩展的项目中。
例如https://github.com/fxnoob/gesture-control-chrome-extension/blob/master/src/default_plugins/tab.js
#17 楼
否。将浏览器环境移植到节点将是一项巨大的努力。我正在研究单元测试的另一种方法是创建jQuery的“模拟”版本,该版本提供回调只要选择被调用。
这样您便可以进行单元测试您的jQuery插件,而不必实际一个DOM。您仍然必须在真实的浏览器中进行测试,以查看您的代码是否可以正常运行,但是,如果您发现浏览器特定的问题,则也可以轻松地“模拟”单元测试中的问题。
一旦准备好显示,我就将其推送到github.com/felixge。
评论
我喜欢这个主意...应该很容易做到。
– Sudhir Jonathan
2010年8月19日在15:12
#18 楼
您可以使用Electron,它允许混合使用浏览器js和nodejs。之前,我尝试在nodejs中使用canvas2d,但最终我放弃了。默认情况下,nodejs不支持它,并且安装起来太困难了(很多... dependeces)。
在使用Electron之前,我可以轻松地使用所有以前的browserjs代码,甚至是WebGL,并传递结果值(例如将结果base64图像数据)转换为nodejs代码。
#19 楼
从来没听说过。 DOM是客户端的东西(jQuery不会解析HTML,而是DOM)。这里有一些当前的Node.js项目:
https:// github.com/ry/node/wiki(https://github.com/nodejs/node)
SimonW的djangode非常酷...
评论
我希望这是可能的。我已经尝试过将jquery包含在node.js项目中,但是当然没有用。 jQuery基于文档/窗口。 Rhino能够运行jQuery服务器端:ejohn.org/blog/bringing-the-browser-to-the-server我要寻找更多的解析器。也许有一种不依赖于浏览器。
–约翰
09年11月26日在2:46
@John:jQuery可以在Rhino上运行的唯一原因是由于该项目:github.com/jeresig/env-js/blob/master/src/env.js它模拟了DOM和JavaScript运行时的一小部分。它依赖于Java api,因此对Node.js(使用V8 / C ++)来说是个难事。
–新月鲜
09年11月26日在4:13
@Nosredna虽然在您编写时可能确实如此,但显然不再如此。我建议您现在删除答案。
–基思·皮森(Keith Pinson)
2014年8月8日15:25
#20 楼
一种替代方法是使用Underscore.js。它应该提供您可能希望从JQuery在服务器端使用的功能。评论
你可以解释吗? jQuery提供了大量的DOM操作/遍历/过滤API。下划线看起来像与DOM无关的通用库实用程序。
– Peter Lyons
2011年3月5日在1:09
同样在这里,我看不到这是如何相关的,两者是互补的,而不是替代的
–易江
2011-3-20在7:37
这个答案不是完全错误的。 jQuery和Underscore确实重叠:它们都提供诸如forEach之类的功能。
– tuomassalo
2011年9月9日下午16:28
-1它们具有重叠的功能,但是Underscore并不是jQuery的替代品。
–山姆
11年3月3日在20:32
问题是关于DOM操作/选择器的问题。
– mikermcneil
13年3月25日在1:05
评论
我想知道:为什么可以在服务器端使用而又可以在客户端使用?也许您可能想创建一个Web刮板,该刮板会定期刮擦特定信息并将结果存储在数据库中?从客户端这是不实际的。
您还应该看看phantomjs,它允许您使用V8引擎模拟浏览器服务器端。
在制作搜寻器时,服务器端的@deeperx DOM操作可能很有用。请参阅此答案。
是的-看一下这个答案-我更喜欢使用cheerio,因为您可以获得jQuery选择器的全部功能。