Which product are you using?
PDF.js Express Plus
PDF.js Express Version
8.7.4
Detailed description of issue
My application needs to merge annotations into a PDF. The annotations are extracted to xfdf form from a WebViewer session using annotationManager.exportAnnotations()
. The PDFs are stored on our server. Our server uses the HTTP Authorization header for authentication. In the code below, I’ve followed the guide “Merging XFDF using the Express REST API” as closely as possible, adding the ‘headers’ field to the form data sent to the API, but I always get the error { error: { code: 21, message: 'Cannot retrieve file from URL.' } }
. I get the same result when I used the @pdftron/jspdf-express-utils
helper library.
I can confirm that this code works for unsecured documents because I get the proper output when replacing the url with a link to a dummy PDF on the W3’s web site. I’m also sure that the url is correct, because copying and pasting the url into
curl -H "Authorization: <myauthorizationcode>" "<url>"
returns the expected binary PDF file. I can also load the document properly in a WebViewer session with the code:
const headers = { 'Authorization': "myauthorizationcode" } instance.UI.loadDocument(url, { filename: "<url>", customHeaders: headers });
Incidentally, when making the call to the merge API, I don’t see anything appear in the access logs for my website, so I’m not sure how it decides that it “Cannot retrieve file”. In any event, here is an example of the headers that it would see returned from my server:
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, PATCH, HEAD
Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Range, Content-Disposition, upload-length, upload-name, upload-offset, continuationtoken
Access-Control-Expose-Headers: Accept-Ranges, Content-Encoding, Content-Length, Content-Range
Content-disposition: attachment; filename="<nameofpdf>.pdf"
Content-type: application/pdf
Content-length: 411233
Date: Thu, 14 Dec 2023 17:38:50 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Expected behaviour
The API should return a link to the merged file.
Does your issue happen with every document, or just one?
Every document
Link to document
For security reasons, I cannot.
Code snippet
const FormData = require('form-data')
const fetch = require('node-fetch')
const xfdf = "a valid xfdf document"
(async function() {
const form = new FormData();
form.append('xfdf', xfdf);
form.append('file', 'https://<my.domain.com>/api/attachment/<attachmentid>/1');
form.append('headers', JSON.stringify({
Authorization: '<myauthorizationcode>'
}));
const response = await fetch('https://api.pdfjs.express/xfdf/merge', {
method: 'post',
body: form
}).then(resp => resp.json());
console.log(response)
})();