是否可以使用 Node.js 在服务器端使用 jQuery 选择器/DOM 操作?
更新(2018 年 6 月 27 日):似乎对 jsdom
进行了重大更新,导致原始答案不再有效。我找到了解释如何使用 jsdom
现在的 this 答案。我已经复制了下面的相关代码。
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); });
是的,您可以使用我创建的名为 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);
, express = Express.createServer();
和 TypeError: Express.createServer is not a function
知道吗?
npm install --save express
。
在撰写本文时,还有维护的 Cheerio。
专为服务器设计的核心 jQuery 的快速、灵活和精简的实现。
:gt(1)
使用 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
中):
节点爬虫.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
最后:
节点爬虫.js
以下链接
下一步将是关注链接。假设您想列出 SO 上每个热门问题的所有海报。您必须首先列出所有热门问题(上面的示例),然后输入每个链接,解析每个问题的页面以获取相关用户的列表。
当您开始关注链接时,可以开始 callback hell。为避免这种情况,您应该使用某种承诺、期货或其他方式。我总是把 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
运行测试:
节点爬虫.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
切里奥
异步
在 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。
var $ = require("jquery"); $.ajax // undefined
(暂时被否决)。
npm install jquery
吗?
> 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
我相信现在的答案是肯定的。
https://github.com/tmpvar/jsdom
var navigator = { userAgent: "node-js" };
var jQuery = require("./node-jquery").jQueryInit(window, navigator);
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);
});
可以使用以下方式安装 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
您必须使用新的 JSDOM API 来获取窗口。
const jsdom = require("jsdom");
const { window } = new jsdom.JSDOM(`...`);
var $ = require("jquery")(window);
...
) 应该是 .JSDOM("<!DOCTYPE html>") 以支持 HTML5?
首先安装它
npm install jquery -S
安装好之后就可以使用了
import $ from 'jquery';
window.jQuery = window.$ = $;
$(selector).hide();
您可以查看我在此处编写的完整教程:https://medium.com/fbdevclagos/how-to-use-jquery-on-node-df731bd6abc7
警告
如 Golo Roden 所述,该解决方案不正确。这只是帮助人们使用 Node 应用程序结构运行他们的实际 jQuery 代码的快速解决方案,但这不是 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();
});
我的工作代码是:
npm install jquery
接着:
global.jQuery = require('jquery');
global.$ = global.jQuery;
或者如果窗口存在,则:
typeof window !== "undefined" ? window : this;
window.jQuery = require('jquery');
window.$ = window.jQuery;
这些解决方案都没有帮助我的 Electron App。
我的解决方案(解决方法):
npm install jquery
在您的 index.js
文件中:
var jQuery = $ = require('jquery');
在您的 .js
文件中以这种方式编写您的 jQuery 函数:
jQuery(document).ready(function() {
从 jsdom v10 开始,不推荐使用 .env() 函数。在尝试了很多需要 jquery 的事情之后,我做了如下所示:
var jsdom = 需要('jsdom');常量 { JSDOM } = jsdom;常量 { 窗口 } = 新的 JSDOM(); const { 文档 } = (new JSDOM('')).window; global.document = 文档; var $ = jQuery = require('jquery')(window);
希望这对您或遇到此类问题的任何人有所帮助。
TypeError: JSDOM is not a constructor
$.each
。我只是包括了这些行,然后像下面这样:$.each(errors, function (ind,error) { res.send(error.msg);console.log(error.msg); });
希望这会有所帮助!
是的,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
我手动简单地完成了它,没有任何额外的包或代码。
npm i jquery
然后我将 jquery.min.js
文件从 node_modules/jquery/dist
目录复制到 public/js
<script type='text/javascript' src='/js/jquery.min.js'></script>
<script>
$(document).ready(function() { console.log( "ready!" ); });
</script>
它会起作用。测试它
注意复制/粘贴文件不是理想的事情,您可以通过将文件启用为静态文件来将文件启用为静态文件,以便 expressJS 可以读取它。但我更容易将其复制到静态公共目录。
不。将浏览器环境移植到节点将是一项相当大的工作。
我目前正在研究单元测试的另一种方法是创建 jQuery 的“模拟”版本,该版本在调用选择器时提供回调。
这样你就可以在没有 DOM 的情况下对你的 jQuery 插件进行单元测试。您仍然需要在真实的浏览器中进行测试,以查看您的代码是否在野外工作,但如果您发现浏览器特定的问题,您也可以轻松地在单元测试中“模拟”这些问题。
一旦准备好展示,我会将一些内容推送到 github.com/felixge。
您可以使用 Electron,它允许混合 browserjs 和 nodejs。
之前尝试过在nodejs中使用canvas2d,最后还是放弃了。 nodejs 默认不支持它,安装起来太难了(很多很多...依赖)。在我使用 Electron 之前,我可以轻松地使用我以前的所有 browserjs 代码,甚至是 WebGL,并将结果值(例如结果 base64 图像数据)传递给 nodejs 代码。
从来没听说过。 DOM 是客户端的东西(jQuery 不解析 HTML,而是解析 DOM)。
以下是一些当前的 Node.js 项目:
https://github.com/ry/node/wiki (https://github.com/nodejs/node)
SimonW 的 djangode 非常酷……
另一种方法是使用 Underscore.js。它应该从 JQuery 提供您可能想要的服务器端。
不定期副业成功案例分享
require("...").env is not a function
。