背景:我正在开发一个生成式人工智能应用程序,基本上用户将文档上传到云存储(通过服务帐户),一旦该文档到达云存储,就会通过文档人工智能进行获取和评估,生成一些数据想要显示给用户。评估完成后,该数据将存储在 firestore 中,包括所分析文档的云存储 URL。在前端,用户可以看到所有分析文档的列表。
问题就在这里:当用户单击此列表中的一项来查看他们的分析时,它会以易于理解的格式显示分析后的数据,以及他们上传的文档的预览。目前,我可以毫无问题地显示分析的数据,但在显示分析的文档的预览时遇到问题。该文档将是 PDF 或某种形式的图像,因此我决定使用
react-pdf
在前端渲染 pdf。然而,当尝试渲染 PDF 时,我不断遇到 CORS 策略问题,特别是 No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
这是我在存储桶上设置的 cors 策略:
[{"origin": ["http://localhost:3500/"],"responseHeader": ["Content-Type","Cache-Control"],"method": ["GET", "HEAD","OPTIONS"]}]
为了进一步参考,这就是我的
react-pdf
组件的样子:
<Document
file={*PDF URL HERE* || ''}
options={{
withCredentials: true,
httpHeaders: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, HEAD',
'Access-Control-Allow-Headers': 'Content-Type'
}
}}
loading={
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}
>
<CircularProgress />
</Box>
}
error={'Failed to load PDF preview'}
>
<Page
pageNumber={1}
height={300}
/>
</Document>
即使设置了 cors 策略,我仍然遇到同样的错误。我试图将我的存储桶保密,但是即使它是公开的,我觉得我还是会遇到同样的问题。我也不想使用 iframe,因为我想尝试更好地理解 CORS 策略,而 iframe 更难设计样式
在您的情况下,您希望直接从浏览器授予对存储桶的访问权限。
首先,如果您使用私有存储桶执行此操作,它将不起作用,因为浏览器无法将正确的凭据添加到 Cloud Storage API(访问令牌)。
解决方案是将存储桶设置为公共并配置 CORS
但是,因为它是用户上传的文档,可能是机密或敏感的,所以公共存储桶不是一个选择。
这里的解决方案是提出一个签名 URL 以允许浏览器下载文件。因为它是 URL 上的 GET,所以 CORS 不应该成为问题(CORS 是 PUT、POST、PATH 和 DELETE 动词上的预检请求。通常 GET 不受影响但我不是前端专家)。
然后,因为您已经在浏览器上下载了文件,所以反应代码应该能够显示它。
另一种选择是使用后端来提供 PDF。我不喜欢这个选项,特别是当 PDF 很大时,因为它会减慢你的后端(饱和度)并且在出口方面会花费更多。
正确的选项是 2 的组合:在服务器端生成缩略图/概述并从后端提供它们。要下载整个 PDF,请使用签名 URL