p5.js
p5.js copied to clipboard
Add 'credentials: include' to fetch request in loadImage()
Most appropriate sub-area of p5.js?
- [ ] Color
- [ ] Core/Environment/Rendering
- [ ] Data
- [ ] Dom
- [ ] Events
- [x] Image
- [ ] IO
- [ ] Math
- [ ] Typography
- [ ] Utilities
- [ ] WebGL
- [ ] Other (specify if possible)
New feature details:
I recently found an issue with p5.js loadImage()
and how the fetch()
request handled cookies in Safari (macOS/iOS) and Chrome (iOS). Due to Apple-specific security features, cookies were not being attached for image requests.
I'm using Express.js middleware to manage user sessions/issue cookies and the requests from loadImage()
were not aware of the session cookie, causing the request to fail. This can evidently be fixed by including credentials: include
in the fetch request.
If possible, this would be a useful addition to the library for others who encounter a similar situation.
+1
The lack of this feature makes p5.js pretty much incompatible with Safari when using private assets. We need the cookie from the client to identify the user's session and their ability to access different assets.
Is there a workaround where we can get the assets with an http request and then use the HTMLImageElement as the image to be loaded?
Something like this would be great
const myImage = new Image(100, 200);
myImage.src = 'picture.jpg';
const p5Image = loadImage(myImage)
// or
const p5Image = image(myImage)
I imagine I can manually get the pixels of the HTMLImageElement and transfer them to a p5.Image using createImage
and modifying the pixels one by one, but I'm asking in case there's a better way of doing it
I've implemented the following workaround, in case someone find it useful
const getImage = async path => {
const response = await fetch(path, {
credentials: 'include'
})
const blob = await response.blob()
const resourceUrl = URL.createObjectURL(blob)
return window.loadImage(resourceUrl) // this is p5.js loadImage
}
This creates a local url to a blob and tells p5js to load the resource at that url. That way you can control the fetching and send the cookies that you want
If credentials are sent with the request, the responding server cannot reply with a header of Access-Control-Allow-Origin: *
which will cause problem with using cross origin requested images.
One thing we can possibly do is to overload the function so that for the first argument instead of just providing the path to the image, you can provide a Request
object which will be passed directly to fetch
. That way you can setup the fetch request however you like, including using POST
requests and custom headers.
I think overloading the function sounds like a very good plan. I like the idea of sending a Request
as the argument, so developers have full control about how they request assets
Is anyone currently working on this?
Not yet @Ashley-Y-Lin!
Ok! I'd like to try working on this, and will start with the suggestion above to overload the function.
Sounds good, I'll assign this to you!
@davepagurek @Ashley-Y-Lin , should I raise a PR with required changes if no one is working on this currently?
@ayushanand308 I think that should be ok! But @Ashley-Y-Lin feel free to let us know if you're still interested but could use some help.