将文件上传到 DigitalOcean Spaces,获取“从源 (url) 访问 (url) 处的 XMLHttpRequest 已被 CORS 策略阻止”

Bri*_*rns 3 javascript cors digital-ocean

控制台中的完整错误是

在 (imageurl) 处访问 XMLHttpRequest from origin ' http://localhost:3000 ' 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:不存在 'Access-Control-Allow-Origin' 标头在请求的资源上。

我尝试将 CORS 配置设置为允许在所有域上进行 PUT 和 POST,但仍然出现错误。

客户端的代码是这样的——

// digitalOcean.js
import AWS from 'aws-sdk'

const regionName = 'nyc3'
const accessKeyId = 'KEYID'
const accessSecretKey = 'SECRETKEY'
export const bucketName = 'BUCKETNAME'

const endpointUrl = `${regionName}.digitaloceanspaces.com`
export const bucketUrl = `https://${bucketName}.${endpointUrl}/`

const spacesEndpoint = new AWS.Endpoint(endpointUrl)
export const s3 = new AWS.S3({
  endpoint: spacesEndpoint,
  accessKeyId: accessKeyId,
  secretAccessKey: accessSecretKey,
})
Run Code Online (Sandbox Code Playgroud)

// getItem.jsx
import * as digitalOcean from '../services/digitalOcean'

function uploadFile(file) {
  const params = { Body: file, Bucket: digitalOcean.bucketName, Key: file.name }
  digitalOcean.s3.putObject(params)
    .on('build', request => {
      request.httpRequest.headers.Host = digitalOcean.bucketUrl
      request.httpRequest.headers['Content-Length'] = file.size
      request.httpRequest.headers['Content-Type'] = file.type
      request.httpRequest.headers['x-amz-acl'] = 'public-read'
    })
    .send((err, data) => {
      if (err) return alert(JSON.stringify(err))
      // ...
    })
}
Run Code Online (Sandbox Code Playgroud)

知道可能是什么问题吗?

Bri*_*rns 8

我最终通过将 Allowed Headers 设置为 * 也让它工作,就像这样 -

截图1 截图2

  • 使用这样的通配符不是很安全。尝试检查我的答案/sf/answers/4922067741/。您可能需要更多检查标头,例如 POST 或 PUT。 (2认同)

Myt*_*iac 7

写下这篇文章是为了对未来的读者有所帮助:

我遇到了类似的问题,我们使用带有 DigitalOcean 空间存储后端的预签名 URL 来进行多部分文件上传。

最初,由于 DigitalOcean 空间响应中缺乏 CORS 策略,请求完全失败。经过一番挖掘,发现您可以在 DO 空间管理仪表板中配置 CORS 策略。

我们遇到的下一个问题是客户端(浏览器)无法访问 DigitalOcean 空间发送的 ETag 响应标头,因为它缺少Access-Control-Expose-Headers允许访问 ETag 标头的标头。为了解决这个问题,似乎没有一个官方的 DigitalOcean 支持的方法来做到这一点,但幸运的是我找到了这个线程,它展示了如何直接使用 s3cmd 来做到这一点:

使用 s3cmd,可以将 CORS 策略文件直接上传到存储桶,这也适用于 DigitalOcean 空间。这会覆盖存储桶上设置的任何现有 CORS 设置

CORS 策略文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <ExposeHeader>ETag</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>
Run Code Online (Sandbox Code Playgroud)

请注意我们如何ExposeHeader在 DigitalOcean 仪表板上已可管理的设置之上定义此处的属性。我不知道为什么官方 UI 中省略了该选项。

配置好文件和 s3cmd 后,上传到存储桶就非常简单:

s3cmd setcors FILE s3://BUCKET