LiveView Uploader getting 403 error -- CORS header “Access-Control-Allow-Origin” missing

Testing LiveView Upload S3 signed upload from development machine(localhost:4000) and getting the message “External client failure”. Upon logging the hook uploader in app.js I see this error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://secret-bucket.s3.amazonaws.com/. (Reason: CORS header “Access-Control-Allow-Origin” missing).

I tried adding
xhr.setRequestHeader('Access-Control-Allow-Origin', '*');

to the request but no change. Is this actually a response error? Does this mean that the change needs to be made on the amazon s3 bucket/instance? Or should the change be made in the phoenix router(or alternatively, add the corsica elixir module?). Bit confused here…

dependencies:

  phoenix 1.6.0
  phoenix_ecto 4.4.0
  phoenix_html 3.0.4
  phoenix_live_dashboard 0.5.2
  phoenix_live_reload 1.3.3
  phoenix_live_view 0.16.4

in app.js:

let Uploaders = {}
Uploaders.S3 = function(entries, onViewError){
  entries.forEach(entry => {
    console.log("entry")
    console.log(entry)
    let formData = new FormData()
    let {url, fields} = entry.meta
    console.log("url")
    console.log(url)
    
    console.log("fields")
    console.log(fields)
    
    Object.entries(fields).forEach(([key, val]) => formData.append(key, val))
    formData.append("file", entry.file)
    let xhr = new XMLHttpRequest()
    onViewError(() => xhr.abort())
    xhr.onload = () => ((xhr.status === 204 || 200) ? entry.progress(100) : entry.error())
    xhr.onerror = () => entry.error()
    xhr.upload.addEventListener("progress", (event) => {
      console.log("addEventListener event")
      console.log(event)
  
      if(event.lengthComputable){
        let percent = Math.round((event.loaded / event.total) * 100)
        if(percent < 100){ entry.progress(percent) }
      }
    })
    xhr.open("POST", url, true)
    xhr.setRequestHeader('Access-Control-Allow-Origin', '*');
    xhr.send(formData)
  })
}
1 Like

I don’t have a link handy but I believe you need to change a setting on your S3 bucket itself to allow uploads from localhost:4000

That was it, thanks. It uploaded. This is how I set the CORS policy on the S3 bucket. It is way to open but a good starting point if you’re debugging.

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
           "GET",
           "PUT",
           "POST",
           "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "x-amz-server-side-encryption",
            "x-amz-request-id",
            "x-amz-id-2"
        ],
        "MaxAgeSeconds": 3000
    }
]
1 Like

Ah, I’m glad that it helped. Thanks for posting back with your solution :+1:

1 Like
1 Like