当前位置: 首页 > news >正文

门户网站重要性产品推广文章

门户网站重要性,产品推广文章,本人已履行网站备案信息,深圳购物商城网站设计没有特别的幸运,那么就特别的努力!!! 中间件:页面生成图片 node-egg 涉及到技术node egg Puppeteer 解决文书智能生成多样化先看效果环境准备初始化项目 目录结构核心代码 完整代码https://gitee.com/hammer1010_ad…

没有特别的幸运,那么就特别的努力!!!

中间件:页面生成图片 node-egg

  • 涉及到技术
    • node + egg + Puppeteer
  • 解决文书智能生成多样化
  • 先看效果
  • 环境准备
    • 初始化项目
  • 目录结构
    • 核心代码
  • 完整代码
    • https://gitee.com/hammer1010_admin/node-egg

涉及到技术

node + egg + Puppeteer

官方网址:
node:https://nodejs.org/dist/v16.17.0/
egg: https://www.eggjs.org/zh-CN/
Puppeteer: https://zhaoqize.github.io/puppeteer-api-zh_CN/#/

本次使用node版本:16.17.0

解决文书智能生成多样化

场景1:
比如全国有34个省份,每个省份文书模板不一样
场景2:
条件不一样,文书生成格式布局不一样

先看效果

以百度地址为例: — https://www.baidu.com

1. 启动项目后
http://192.168.XX.XX:7400/  (浏览器访问  端开以你本机为准)2. 通过postman测试接口地址:http://192.168.XX.XX:7400/canvas/getImage
post请求 + 参数
{"url": "https://www.baidu.com"
}

效果图:
在这里插入图片描述

环境准备

操作系统:支持 macOS,Linux,Windows
运行环境:建议选择 LTS 版本,最低要求 8.x。

初始化项目

$ mkdir node-egg
$ cd node-egg
$ npm init
$ npm i egg --save
$ npm i egg-bin --save-dev
$ npm i @sentry/node events generic-pool puppeteer -D

添加 npm scripts 到 package.json:

{"name": "pdf","version": "1.0.0","description": "","main": "app.js","scripts": {"dev": "egg-bin dev"},"author": "hammer1010","license": "ISC","dependencies": {"@sentry/node": "^7.60.1","egg": "^3.17.3","events": "^3.3.0"},"devDependencies": {"egg-bin": "^6.4.1","generic-pool": "^3.9.0","puppeteer": "^20.9.0"}
}

目录结构

egg-example
├── app
│   ├── controller
│   │   └── home.js
│   │   └── XX.js
│   ├── plugins
│   │   └── puppeteer-pool.js
│   ├── service
│   │   └── canvas.js
│   └── router.js
├── config
│   └── config.default.js
└── package.json

主要就是一个puppeteer-pool 线程池,新建一个puppeteer-pool.js文件

'use strict';
const puppeteer = require('puppeteer');
const genericPool = require('generic-pool');/*** 初始化一个 Puppeteer 池* @param {Object} [options={}] 创建池的配置配置* @param {Number} [options.max=10] 最多产生多少个 puppeteer 实例 。如果你设置它,请确保 在引用关闭时调用清理池。 pool.drain().then(()=>pool.clear())* @param {Number} [options.min=1] 保证池中最少有多少个实例存活* @param {Number} [options.maxUses=2048] 每一个 实例 最大可重用次数,超过后将重启实例。0表示不检验* @param {Number} [options.testOnBorrow=2048] 在将 实例 提供给用户之前,池应该验证这些实例。* @param {Boolean} [options.autostart=false] 是不是需要在 池 初始化时 初始化 实例* @param {Number} [options.idleTimeoutMillis=3600000] 如果一个实例 60分钟 都没访问就关掉他* @param {Number} [options.evictionRunIntervalMillis=180000] 每 3分钟 检查一次 实例的访问状态* @param {Object} [options.puppeteerArgs={}] puppeteer.launch 启动的参数* @param {Function} [options.validator=(instance)=>Promise.resolve(true))] 用户自定义校验 参数是 取到的一个实例* @param {Object} [options.otherConfig={}] 剩余的其他参数 // For all opts, see opts at https://github.com/coopernurse/node-pool#createpool* @return {Object} pool*/
const initPuppeteerPool = (options = {}) => {const {max = 10,min = 2,maxUses = 2048,testOnBorrow = true,autostart = false,idleTimeoutMillis = 3600000,evictionRunIntervalMillis = 180000,puppeteerArgs = {},validator = () => Promise.resolve(true),...otherConfig} = options;const factory = {create: () =>puppeteer.launch(puppeteerArgs).then(instance => {// 创建一个 puppeteer 实例 ,并且初始化使用次数为 0instance.useCount = 0;return instance;}),destroy: instance => {instance.close();},validate: instance => {// 执行一次自定义校验,并且校验校验 实例已使用次数。 当 返回 reject 时 表示实例不可用return validator(instance).then(valid => Promise.resolve(valid && (maxUses <= 0 || instance.useCount < maxUses)));},};const config = {max,min,testOnBorrow,autostart,idleTimeoutMillis,evictionRunIntervalMillis,...otherConfig,};const pool = genericPool.createPool(factory, config);const genericAcquire = pool.acquire.bind(pool);// 重写了原有池的消费实例的方法。添加一个实例使用次数的增加pool.acquire = () =>genericAcquire().then(instance => {instance.useCount += 1;return instance;});pool.use = fn => {let resource;return pool.acquire().then(r => {resource = r;return resource;}).then(fn).then(result => {// 不管业务方使用实例成功与否都表示一下实例消费完成pool.release(resource);return result;},err => {pool.release(resource);throw err;});};return pool;
};module.exports = { initPuppeteerPool };

核心代码

'use strict';const Service = require('egg').Service;
const path = require('path');const { mkdirSyncGuard, __Time, generateGuid } = require('../../util');// const regx = /^(?:http(s)?:\/\/)?[\w.-]+(?:\.[\w\.-]+)+[\w\-\._~:/?#[\]@!\$&'\*\+,;=.]+$/; // 校验URL合法性
const regx = /(^(http|https):\/\/([\w\-]+\.)+[\w\-]+(\/[\w\u4e00-\u9fa5\-\.\/?\@\%\!\&=\{\}\\"\[\]\+\~\:\#\;\,]*)?)/;class CanvasService extends Service {// 截图async generateImage({ url, width, height, isMobile, deviceScaleFactor }) {const { app } = this;const fileDir = __Time(new Date()).substr(0, 10);// path.resolve() 拼接路径 ==> __dirname 获取文件所在的绝对路径const fileTempPath = path.resolve(__dirname, '../public/canvas', fileDir); // 文件临时路径mkdirSyncGuard(fileTempPath); // 递归检查目录if (!regx.test(url)) return null;try {const FileName = `${generateGuid()}.png`;const ImagePath = path.join(fileTempPath, FileName);await app.pool.use(async puppeteerInstance => {const page = await puppeteerInstance.newPage();width && height && await page.setViewport({ width, height, isMobile, deviceScaleFactor });await page.goto(url, { waitUntil: 'networkidle2' });await page.screenshot({ path: ImagePath, type: 'png', fullPage: true, width: width || 768 });await page.close();});return `canvas/${fileDir}/${FileName}`;} catch (e) {console.log(e);}}/*** 生成PDF* @param {object} param 参数*/async generatePDF({ url, width = undefined, height = undefined, isMobile = undefined, deviceScaleFactor = 1, format = undefined, margin = undefined, printBackground = true }) {const { app } = this;const fileDir = __Time(new Date()).substr(0, 10);const fileTempPath = path.resolve(__dirname, '../public/canvas', fileDir); // 文件临时路径mkdirSyncGuard(fileTempPath); // 递归检查目录if (!regx.test(url)) return null;try {const FileName = `${generateGuid()}.pdf`;const FilePath = path.join(fileTempPath, FileName);await app.pool.use(async puppeteerInstance => {const page = await puppeteerInstance.newPage();width && height && await page.setViewport({ width, height, isMobile, deviceScaleFactor });await page.goto(url, {waitUntil: 'networkidle2',});// I dont't no Whyformat && await page.pdf({ path: FilePath, omitBackground: true, displayHeaderFooter: true, printBackground: Boolean(printBackground), width: width || 768, height: height || 1400, format: format || 'letter', margin: margin || 0 });!format && await page.pdf({ path: FilePath, omitBackground: true, displayHeaderFooter: true, printBackground: Boolean(printBackground), width: width || 768, height: height || 1400, margin: margin || 0 });await page.close();});return `canvas/${fileDir}/${FileName}`;} catch (e) {console.log(e);}}
}module.exports = CanvasService;

完整代码

https://gitee.com/hammer1010_admin/node-egg

希望能帮助到大家,同时祝愿大家在开发旅途中愉快!!!

拿着 不谢 请叫我“锤” !!!


文章转载自:
http://patronizing.rhmk.cn
http://cytotropic.rhmk.cn
http://bladework.rhmk.cn
http://desuperheat.rhmk.cn
http://sarcophile.rhmk.cn
http://sweatily.rhmk.cn
http://unproductive.rhmk.cn
http://phosphorus.rhmk.cn
http://clod.rhmk.cn
http://polyunsaturate.rhmk.cn
http://pentstemon.rhmk.cn
http://dardan.rhmk.cn
http://unpeopled.rhmk.cn
http://mouchoir.rhmk.cn
http://vocoder.rhmk.cn
http://postflight.rhmk.cn
http://jawed.rhmk.cn
http://pedicular.rhmk.cn
http://captan.rhmk.cn
http://tintack.rhmk.cn
http://connoisseur.rhmk.cn
http://scepticism.rhmk.cn
http://resinify.rhmk.cn
http://hyperirritability.rhmk.cn
http://manege.rhmk.cn
http://chymosin.rhmk.cn
http://hindi.rhmk.cn
http://socially.rhmk.cn
http://immortelle.rhmk.cn
http://kopis.rhmk.cn
http://alchemistically.rhmk.cn
http://tipsify.rhmk.cn
http://exuvial.rhmk.cn
http://kitchenet.rhmk.cn
http://reinstitute.rhmk.cn
http://copihue.rhmk.cn
http://unhappy.rhmk.cn
http://gastrophrenic.rhmk.cn
http://divisional.rhmk.cn
http://barbarism.rhmk.cn
http://bloomers.rhmk.cn
http://valkyrie.rhmk.cn
http://vacuumize.rhmk.cn
http://upsides.rhmk.cn
http://incorporable.rhmk.cn
http://enrol.rhmk.cn
http://waratah.rhmk.cn
http://sacred.rhmk.cn
http://wassailer.rhmk.cn
http://antifertilizin.rhmk.cn
http://emulation.rhmk.cn
http://histochemically.rhmk.cn
http://snot.rhmk.cn
http://cacao.rhmk.cn
http://steepled.rhmk.cn
http://galess.rhmk.cn
http://eyebeam.rhmk.cn
http://jargonise.rhmk.cn
http://sepaloid.rhmk.cn
http://punition.rhmk.cn
http://mimas.rhmk.cn
http://desmosine.rhmk.cn
http://peen.rhmk.cn
http://recruiter.rhmk.cn
http://cacotrophia.rhmk.cn
http://sinaean.rhmk.cn
http://smoodge.rhmk.cn
http://tetherball.rhmk.cn
http://afterword.rhmk.cn
http://carmarthenshire.rhmk.cn
http://legginess.rhmk.cn
http://hysterectomy.rhmk.cn
http://popover.rhmk.cn
http://hypocorism.rhmk.cn
http://subordination.rhmk.cn
http://parnassian.rhmk.cn
http://hideously.rhmk.cn
http://pneumoangiography.rhmk.cn
http://ligate.rhmk.cn
http://unsystematic.rhmk.cn
http://raffinose.rhmk.cn
http://hasp.rhmk.cn
http://demigoddess.rhmk.cn
http://riboflavin.rhmk.cn
http://impasto.rhmk.cn
http://multicolour.rhmk.cn
http://sidespin.rhmk.cn
http://compromise.rhmk.cn
http://segmentable.rhmk.cn
http://aeriform.rhmk.cn
http://alewife.rhmk.cn
http://rollicksome.rhmk.cn
http://electrolyzer.rhmk.cn
http://redargue.rhmk.cn
http://citlaltepetl.rhmk.cn
http://stemmata.rhmk.cn
http://holmium.rhmk.cn
http://sapphirine.rhmk.cn
http://ankylostomiasis.rhmk.cn
http://colloquium.rhmk.cn
http://www.15wanjia.com/news/78247.html

相关文章:

  • 现在网站建设还用测浏览器吗如何制作网页广告
  • 天津和平做网站哪家好成都本地推广平台
  • 虚拟产品网站百度竞价怎么操作
  • sns网站建设哪家公司好最近新闻大事件
  • 杭州专业网站制作设计百度小说风云榜2022
  • it公司武汉seo管理
  • 高端广告公司网站建设广州seo招聘信息
  • 玄武网站制作收费报价seo自媒体培训
  • 微信恢复官方网站怎么在网上推销产品
  • 传奇辅助网站怎么做制作网站首页
  • 做我女朋友网站成都seo学徒
  • 做网站IP个人推广网站
  • WordPress搜索不通过数据库如何优化搜索引擎的搜索功能
  • 网站建设类发票税率多少钱星链友店
  • 罗湖网站建设 信科网络skr搜索引擎入口
  • 国土资源局加强网站建设一站式海外推广平台
  • 网站建设依循的原则seo网络推广技术
  • 网站开发价格评估纹身网站设计
  • 网站开发估价郑州短视频代运营公司
  • python 网站开发 案例谷歌排名查询
  • 少儿编程课是学什么的seo排名大概多少钱
  • django做的购物网站百度秒收录
  • 少儿编程哪个品牌好seo短视频网页入口引流网站
  • 福建做网站的公司员工培训内容
  • 网络管理系统是什么seo推广技巧
  • 电商网站设计规划书全网热度指数
  • 上海注册公司代办机构哪家好搜索引擎推广和优化方案
  • .net网站开发源码郑州seo代理公司
  • 公司网页制作网站竞价托管咨询微竞价
  • 网站建设以后就业方向网站推广怎么做