react-doc-viewer
react-doc-viewer copied to clipboard
Error 404 when accessing s3 urls for docx even if it is existing
Hi,
Has anyone encountered this error when accessing s3 urls via DocViewerRenderers?
The scenario is, I am passing an s3 url docx file, once I render the document, the initial response is 404 but then after a while, the document will load and everything is fine but sometimes the documents is just stuck on loading. But everytime I reopen/rerender via the react-doc-viewer, it returns a response of 404 first before loading the document.
Appreciate all the assistance. Thank you!
I am also seeing this issue once the application is hosted on S3. I do not see this when running locally though. What I did have to do (locally) was ensure that when loading the document to S3, it was using the proper contentType to S3:
const parsedPath = path.parse(file.originalname);
const parsedExtension = parsedPath.ext?.toLowerCase() || '';
switch (parsedExtension) {
case '.pdf':
contentType = 'application/pdf';
break;
case '.jpg':
contentType = 'image/jpeg';
break;
case '.jpeg':
contentType = 'image/jpeg';
break;
case '.png':
contentType = 'image/png';
break;
case '.docx':
contentType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
break;
case '.xlsx':
contentType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
break;
case '.zip':
contentType = 'application/zip';
break;
}
await this.s3Service.putObject({
Bucket: this.awsConfig.s3UploadBucketName,
Key: fileDropLocation,
Body: fileStream,
ContentType: contentType,
});
You may also want to be sure CORS is allowed on the bucket that is hosting the file(s):
[
{
"AllowedHeaders": [
"Authorization"
],
"AllowedMethods": [
"GET"
],
"AllowedOrigins": [
"*"
],
"ExposeHeaders": [],
"MaxAgeSeconds": 3000
}
]
Or more restrictive if you know what the origins will be.
If you are in the same situation as I am, I am starting to make sure it isn't network (NACL, SG) related.
So, I did figure out the issue, and I have seen this before...
If you are using a role to create a pre-signed URL, it does some funky things. Using IAM user credentials (and I limit this specifically for pre-signed URLs and also accessing the key Id and secret via Secrets Manager), it works fine. The generated URL is all sorts of jacked up (with the same permissions) via the lambda role.
Sorry forgot to mention that I am not using a pre-signed URL. For now we're using a public url from s3 bucket @jsonpj3wt. I am still figuring out what is the issue by going through the library/package itself.
If you are using a public url, check the metadata on the file it is trying to render. My guess is it is not set properly for ContentType or a CORS issue.
If you go with Pre-signed URLs, the issue is AWS will append the X-Amz-Security-Token
for any role that generates the URL.
My issue might be related to either the URL length or on Microsoft's end since the URL actually works to download with either URL.
Have tried putting a handler on it? I have tried using the loadingRenderer and noRenderer api/components of the package but no luck at all. @jsonpj3wt
Still have a problem when trying to load PDF file from S3, S3 link is public.
S3 link format:
https://<bucket_name>.s3.<aws_region>.amazonaws.com/<file_name>
not sure if anyone has this issue but I had to specify a fileType to render my s3 file
const docs = [{ uri: "____ ", fileType: "pdf" }];
Same here, impossible to get any file from S3, no matter it's file type, it always ends with CORS errors.
I have issue with Azure storage account, that my pdf could render, but not for the excel...
So, I did figure out the issue, and I have seen this before...
If you are using a role to create a pre-signed URL, it does some funky things. Using IAM user credentials (and I limit this specifically for pre-signed URLs and also accessing the key Id and secret via Secrets Manager), it works fine. The generated URL is all sorts of jacked up (with the same permissions) via the lambda role.
@jsonpj3wt Do you happen to remember exactly how it was funky? I'm running into what seems like the same issue, and gone through a whole process verifying that there's not an initial request being cached, content-type is correct, and the CORS configuration is sane. We did relatively recently switch to using service accounts, but the associated policies are exactly the same as they always have been.
Strangely, only .docx, .xlsx, etc files seem to fail. .doc, .pdf, .xls, and others are all fine.
not sure if anyone has this issue but I had to specify a fileType to render my s3 file
const docs = [{ uri: "____ ", fileType: "pdf" }];
It works for me. But I decided to investigate more and finally found a reason in the Fetch. S3 doesn't work with HEAD
method. That is why I set prefetchMethod="GET"
in DocViewer
and now everything is ok.
Adding prefetchMethod="GET"
worked for me
<DocViewer prefetchMethod="GET" style={{ borderRadius: "10px", height: "100%" }}
documents={[{ fileType: selectedDoc?.fileType, fileName: selectedDoc?.name, uri: selectedDoc?.uri }]}
pluginRenderers={DocViewerRenderers}
config={{
loadingRenderer: {
overrideComponent: MyLoadingRenderer,
},
}}
/>
So, I did figure out the issue, and I have seen this before... If you are using a role to create a pre-signed URL, it does some funky things. Using IAM user credentials (and I limit this specifically for pre-signed URLs and also accessing the key Id and secret via Secrets Manager), it works fine. The generated URL is all sorts of jacked up (with the same permissions) via the lambda role.
@jsonpj3wt Do you happen to remember exactly how it was funky? I'm running into what seems like the same issue, and gone through a whole process verifying that there's not an initial request being cached, content-type is correct, and the CORS configuration is sane. We did relatively recently switch to using service accounts, but the associated policies are exactly the same as they always have been.
Strangely, only .docx, .xlsx, etc files seem to fail. .doc, .pdf, .xls, and others are all fine.
In our case, it turned out that this was a URL length issue - Microsoft did not like the URL since we switched to using a pre-signed URL, because the X-Amz-Security-Token
is quite lengthy.
We implemented a custom URL shortener and now everything works fine.
not sure if anyone has this issue but I had to specify a fileType to render my s3 file
const docs = [{ uri: "____ ", fileType: "pdf" }];
Thank you is working fine for me1