你还在用html2canvas软件进行截图吗?那你会遇到图片变糊了的问题,还有些样式方面的问题。
可以采取服务端截图的方式来解决上述问题哦。即puppeteer截取页面的DOM
说到服务端截图,大部分可能是采用puppeteer.goto("url路径"),这种方法的缺陷就是:当你的页面是有登录态的时候,截图结果会不一样;因此,应当采用一种data urls的方式。当你有html代码片段,你怎么浏览你的效果呢?不是将之保存为一个html文件,而是可以直接在浏览器打开:
data:text/html,<p>hello world</p>
下面将的服务端截图便是利用了这个原理。
第一步、安装pupeteer
npm install -g cnpm --registry=https://registry.npm.taobao.org cnpm install puppeteer
第二步、采用pupeteer进行截图
代码如下:
const puppeteer = require('puppeteer'); (async () => { const browser = await (puppeteer.launch({ // 若是手动下载的chromium需要指定chromium地址, 默认引用地址为 /项目目录/node_modules/puppeteer/.local-chromium/ // executablePath: '/Users/huqiyang/Documents/project/z/chromium/Chromium.app/Contents/MacOS/Chromium', //设置超时时间 timeout: 15000, //如果是访问https页面 此属性会忽略https错误 ignoreHTTPSErrors: true, // 打开开发者工具, 当此值为true时, headless总为false devtools: false, // 关闭headless模式, 不会打开浏览器 headless: true })); const page = await browser.newPage(); const html = `<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,viewport-fit=cover,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no"> <title></title> </head> <body style="background: transparent;"> <div class="order-list" data-v-8efee150=""> <div class="item" data-v-8efee150=""><img src="https://gelimalloss.gree.com/gree-mall-v2/images/pay-icon.png" data-v-8efee150=""><span data-v-8efee150="">待付款</span> <div class="marker" data-v-8efee150="" style="display: none;"></div> </div> <div class="item" data-v-8efee150=""><img src="https://gelimalloss.gree.com/gree-mall-v2/images/take-icon.png" data-v-8efee150=""><span data-v-8efee150="">待发货</span> <div class="marker" data-v-8efee150="" style="display: none;"></div> </div> <div class="item" data-v-8efee150=""><img src="https://gelimalloss.gree.com/gree-mall-v2/images/recive-icon.png" data-v-8efee150=""><span data-v-8efee150="">待收货</span> <div class="marker" data-v-8efee150="" style="display: none;"></div> </div> <div class="item" data-v-8efee150=""><img src="https://gelimalloss.gree.com/gree-mall-v2/images/comment-icon.png" data-v-8efee150=""><span data-v-8efee150="">待评价</span> <div class="marker" data-v-8efee150="" style="display: none;"></div> </div> <div class="item" data-v-8efee150=""><img src="https://gelimalloss.gree.com/gree-mall-v2/images/return-icon.png" data-v-8efee150=""><span data-v-8efee150="">退款/售后</span> <div class="marker" data-v-8efee150="" style="display: none;"></div> </div> </div> </body> </html>`; const styleDesc = `.order-list[data-v-8efee150] { display: flex; justify-content: space-evenly; padding: 3.46667vw 2.66667vw 4.8vw } .order-list .item[data-v-8efee150] { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 18.66667vw; position: relative } .order-list .item img[data-v-8efee150] { width: 7.46667vw; height: 7.46667vw; margin-bottom: 3.46667vw } .order-list .item span[data-v-8efee150] { color: #444; line-height: 1; font-size: 3.73333vw; font-family: PingFang SC Medium,PingFang SC Medium-Medium } .order-list .item .marker[data-v-8efee150] { width: 6.4vw; height: 4vw; color: #f85d4c; font-size: 3.2vw; text-align: center; line-height: 4vw; border-radius: 4vw; background: #fff; position: absolute; top: 0; right: 0; font-family: PingFang SC Bold,PingFang SC Bold-Bold; font-weight: 700; border: 1px solid #fa6751 } .order-list .item .marker-one[data-v-8efee150] { width: 4vw; height: 4vw; right: 1.33333vw }` // 这里大部分文章可能会是传一个网络路径,其实大可不必,因为你的网站可能有登录态,无头浏览器打开的不是你登录态下的页面,截图就会出问题
await page.goto(`data:text/html,${html}`, { waitUntil: 'networkidle2' }); page.addStyleTag({ content: styleDesc }) await page.setViewport({ width: 800, height: 200 }) const waitTime = (n) => new Promise((r) => setTimeout(r,n)) await Promise.race([waitTime(2000)]) const el = await page.$('.order-list') await el.screenshot({ path: 'fmall.png', type: 'png', // quality: 100, 只对jpg有效 // fullPage: true, // 指定区域截图,clip和fullPage两者只能设置一个 // clip: { // x: 0, // y: 0, // width: 1000, // height: 40 // } }); browser.close(); })();
执行上面的node文件,就会在项目的根目录下面出现一张图:fmall.png,服务端截图完毕。