简体   繁体   中英

Rendering images in a webshot pdf on Meteor's Galaxy

I have a pdf that is rendered from a server side html file in my Meteor application using webshot. This pdf is displayed in the browser, and also attached to an email to be sent to various users. Since migrating over to Meteor's Galaxy platform, I am unable to render the images in the html file, and the email attachment doesn't work correctly. My set up worked perfectly on Digital Ocean with Ubuntu 14.04, and also on my localhost. It still works perfectly at both of these environments, but doesn't work with Galaxy. (it's worth noting I don't know much about programming email attachments, but used Meteor's email package, which is based on mailcomposer)

The pdf renders, so I know phantomjs is working, and webshot is taking a screenshot and displaying it as a pdf, so I know webshot is working. However, the images won't render and when attaching to an email, the file is corrupted/doesn't send correctly. I have tried logging the html to ensure that the URLs to the image files are all correct, and they are when deployed to Galaxy, but they just won't render with phantomjs/webshot. I am using the meteorhacks:ssr package to render the html file on the server before reading it with phantomjs.

I've tried contacting Galaxy support about this, but haven't had much assistance. Has anyone else experienced this? I'm struggling to even pinpoint the package causing the issue to submit a pull request if I need to. Thanks!

So I figured out my problem, which I'll share with others, but I'll also share a few pointers on debugging webshot in an app running on Galaxy's servers.

First, webshot doesn't pipe errors to the Galaxy's logs by default, as it's running on a spawned node.js process, so you need to change this line in your 'project_path/.meteor/local/isopacks/npm-container/npm/node_modules/webshot/lib/webshot.js' file (note, I'm still on Meteor 1.2, so this is wherever your npm webshot package is located):

// webshot.js line 201 - add , {stdio: "inherit"} to spawn method var phantomProc = crossSpawn.spawn(options.phantomPath, phantomArgs, {stdio: "inherit"});

This passes all logs from the spawned process to your console. In addition to this, comment out the following code in the same file:

// comment out lines 234-239 // phantomProc.stderr.on('data', function(data) { // if (options.errorIfJSException) { // calledCallback = true; // clearTimeout(timeoutID); // cb(new Error('' + data)) // } // });

Doing these two modifications will print logs from the phantomjs process to your Galaxy container. In addition to that, you will want to modify the webshot.phantom.js script that is located in the same directory to print to the console in order to debug. This is the script you will want to modify however you see fit to find your issue, but the phantomjs docs recommend using phantom callbacks to debug errors from the web page being loaded, such as:

page.onResourceError = function(resourceError) {
  console.log('Unable to load resource (#' + resourceError.id + 'URL:' + resourceError.url + ')');
  console.log('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString);
};

For my particular issue, I was getting an SSL handshake issue:

Error code: 6. Description: SSL handshake failed

To fix this, I had to add the following code to my webshot options object:

        phantomConfig: {
          "ignore-ssl-errors": "true",
          "ssl-protocol": "any"
        },

This fixed the issue with loading the static images in my pdf over https (note: this worked correctly on Digital Ocean without the code above, I'm not sure what is different in the SSL configuration on Galaxy's containers).

In addition, I was having issues with attaching the pdf correctly to an email my app sent. This turned out to be an issue with rendering the url correctly for email using Meteor.absoluteUrl() in the mailcomposer attachments filePath object. I don't know why Meteor.absoluteUrl() did not render my app's url correctly on Galaxy in an email attachment, as Meteor.absoluteUrl() works in other places in my app, and it worked on Digital Ocean, but it didn't work here. When I switched the attachment object over to a hard coded URL, it worked fine, so that might be something worth checking if you are having issues.

I know quite a few Meteor developers have used webshot to create pdf's in their app, and I'm sure some will be migrating to Galaxy in the future, so hopefully this is helpful to others who decide to switch to Galaxy. Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM