How to use puppeteer in vue.js

狂风中的少年 提交于 2020-01-24 20:21:07

问题


I'm trying to integrate puppeteer in a vue.js application to generate screenshots and pdf files. I have write a function that use puppeteer to generate a screenshot, works perfectly.

export const MyScripts = {
    getMiniature : async function(elementId, key) {
        const puppeteer = require('puppeteer');
        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        // Making a screenshot
    }
}

When trying to integrate that function, it fails to load puppeteer. The 'require' doesn't generate error, but when I call puppeteer.launch(), I got the following message:

TypeError: nodeFunction is undefined

I've read that puppeteer is not supposed to work with front-end application, so I hope I have not chosen the wrong direction.

So how can I make it work ? If it is not possible, what can I use to generate screenshots or pdf ?

Thanks in advance


回答1:


Puppeteer works with Node, it has nothing to do with Vue. Node.js is pretty much JavaScript running on a server and therefore separated from your frontend. Puppeteer uses a headless browser(and therefore your actualy system) to generate the screenshots and PDF files.

A client-side browser has no access to your filesystem and so therefore you can't use it in a frontend framework like Vue to generate screenshots and save them.

I don't know of any tools to generate screenshots of the current page that are not highly experimental but I am sure you could find some more information when deep-diving stackoverflow.




回答2:


Disclaimer: This will not show you how to run puppeteer (chromium) on client side. This will only show you how to connect to a puppeteer instance running somewhere else.

Right now it's definitely possible on puppeteer version 1.9.0 (with a bit of headache).

Below I listed puppeteer web, client side pdf and image generation and external API.

1. Puppeteer web

It looks like you're trying to bundle puppeteer to use in a web application. Tip-of-tree Puppeteer is much more bundling-friendly and includes the browser field in its package.json that should help with bundling.

One thing you have to understand that the frontend does not have any access to the backend by any means other than REST/WS API. So either you have to use those API or build some api by yourself. You can build a simple express API and use that from the vue app. There are lots of resources and stackoverflow questions for that.

On that note, let's use the shiny puppeteer-web bundle. :)

Run Chrome and get browserWSEndpoint

You need to run chrome somewhere to have this. Probably on the server you are hosting the vue app. Assuming it's the chromium, you can use following code

chromium
--disable-background-networking \
--disable-background-timer-throttling \
--disable-breakpad \
--disable-client-side-phishing-detection \
--disable-default-apps \
--disable-dev-shm-usage \
--disable-extensions \
--disable-features=site-per-process \
--disable-hang-monitor \
--disable-popup-blocking \
--disable-prompt-on-repost \
--disable-sync \
--disable-translate \
--metrics-recording-only \
--no-first-run \
--safebrowsing-disable-auto-update \
--enable-automation \
--password-store=basic \
--use-mock-keychain \
--remote-debugging-port=0

This will result in something like, DevTools listening on ws://127.0.0.1:57683/devtools/browser/foo

Make puppeteer browser version

Clone the puppeteer repo, install all modules and run the command to get specific web version you can embed on your UI.

git clone https://github.com/GoogleChrome/puppeteer
npm install
npm run bundle

You will see a utils/browser/puppeteer-web.js file. That's what you need to embed on your vue or web app.

Require puppeteer browser and connect to the endpoint

<script type="text/javascript" src="puppeteer-web.js"></script>
<script type="text/javascript">
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.connect({
    browserWSEndpoint: theirBrowserWSEndpoint 
    // the exact same browser WS endpoint that just loaded this page, 
    // example, ws://127.0.0.1:57683/devtools/browser/foo
  });

  const page = await browser.newPage();

  .. a whole bunch of operations to perform to data scraping, etc.
})()
</script>

PS: I will write an in depth article/answer about it soon with all kind of screenshots, stay tuned.

2. Capture current page as screenshot and pdf

You can use html2canvas to gather screenshot of current page. It's as simple as calling and using it. vue-resume uses this to generate final image. Useful if you are trying to capture the current page or any part of it.

Example usage,

var element = document.getElementById('capture');
html2canvas(element).then(canvas => {
    document.body.appendChild(canvas) // do whatever want with the image data
});

Same with PDF generation. You can use html2pdf to do that.

var element = document.getElementById('capture');
html2pdf(element); // prompts the user to save the result

3. Screenshot Generation API

If you still need to generate screenshot, you can use available services. Here are some of them, (ps, the list might not be updated in future, and fail to work.)

  • Restpack: https://restpack.io/screenshot
  • Thum: https://www.thum.io
  • URL2PNG: https://www.url2png.com
  • url-to-pdf-api: https://github.com/alvarcarto/url-to-pdf-api


来源:https://stackoverflow.com/questions/52834849/how-to-use-puppeteer-in-vue-js

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!