Recently I’ve been playing with Tone.js, which can play audio loaded from an external URI. For some files that I loaded into the Assets folder, the process of launching Tone.js’s Player with a source pointed at the Asset CDN URI works fine except it appeared that some files would never work at all, failing with a 403 error.
It took me a while to make sense of what was going on, but eventually I figured out that if there was even a single space in the asset filename, then the XHR request would fail as described above.
I have a working example ready to go in one of my playground projects here:
If you go to the glitch app and scroll down to “Resource Examples”, the button marked A in the image down below works correctly and references a file that doesn’t have a space; the button marked B does the same exact thing but it references a file that does have a space, and it doesn’t work.
The browser console log reveals that the request URI doesn’t show anything out of the ordinary, and also confirms that the CDN URI given to me from the Assets page has the proper URI encoding of the space in the filename (%20).
Last, it is only the XHR request retrieving the file that fails. If I make an audio element using the CDN uri or attempt to just load it in-browser, it works fine. This suggests some possible issue with CORS or adjacent code on the CDN side.
Oh that’s an interesting one. It’s trying to load ...%2520..., so it double-escaped the space. The url-safe version of a space is supposed to be %20, but it then turned that % into its own escaped value %25.
Did you copy the URL straight out of the asset property panel?
Hmm, I did a quick check with one of my projects, if I upload an asset with a space in it, it ends up with just %20 in the URL, and if I click the “copy URL” button, I still get just %20 rather than something with %2520.
Looking at the code, the URL you’re plugging in seems to work just fine, so it’s possible that Tone.ToneAudioBuffer runs its own, extra escaping maybe? What happens if you use an actual space in that URL instead of %20? Does it magically load the resource now?
I’m writing another test app to check- I looked at the source for Tone.js and it goes straight to the fetch() api. (I would like to rule out that part of the call chain.)