html `img` tag considered as not same origin?

I have this API that is 100% allowing the client to access it, and now I'm trying make it serve images to the client. so I setup everything and now I can visit the route (dedicated to static files serving) and browse to any file and get that file to show/download in my browser. the only problem is when I use the src attribute of an html img tag, I see this error in the browser: net::ERR_BLOCKED_BY_RESPONSE.NotSameOrigin 200 the url in the src is the same as the one I visit in the browser and the image loads successfully.
30 Replies
Ambushfall
Ambushfall•2y ago
I'm not quite sure what this is about, and I could sound dumb quite frankly, however are you using Next/Image or just img tags? in my case, cross origin img src tags work normally, just the next/image elements don't allow until added to the Next.config
venego
venegoOP•2y ago
then I must be doing something wrong. or this brave-browser is doing something different. leme try other browsers nop blocked on chromium, chrome and brave the controller that handles the media:
const getFile = async (req, res) => {
res.sendFile(req.params.file, {root: `./src/media/${req.params.section}`}, (err) => {
if (err) {
return console.log('file was not sent: ', err);
}
console.log('file was sent');
});
};
module.exports = {getFile};
const getFile = async (req, res) => {
res.sendFile(req.params.file, {root: `./src/media/${req.params.section}`}, (err) => {
if (err) {
return console.log('file was not sent: ', err);
}
console.log('file was sent');
});
};
module.exports = {getFile};
maybe this is the wrong way to do it?
Ambushfall
Ambushfall•2y ago
This is how I've made my image show, not sure if it's relevant to your query as you've provided server code for sending files
<img alt="discord image" src={sessionData?.user?.image?.toString()}/>
<img alt="discord image" src={sessionData?.user?.image?.toString()}/>
venego
venegoOP•2y ago
that's exactly how I do it. but it doesn't seem to work.
venego
venegoOP•2y ago
I found this solution (not happy with): https://stackoverflow.com/questions/50248329/fetch-image-from-api I handle the image as a blob and attach it to the src
Stack Overflow
Fetch image from API
Q1) In my reactjs application, I am trying to fetch an API from my backend Nodejs server. The API responds with an image file on request. I can access and see image file on http://192.168.22.124:3...
venego
venegoOP•2y ago
but it's kinda overkill
Ambushfall
Ambushfall•2y ago
Perhaps the issue lies elsewhere, are you able to scaffold an example where I could try the code and see the difference?
venego
venegoOP•2y ago
ok the express route:
app.use('/media/:file', async (req, res) => {
res.sendFile(req.params.file, {root: `./src/media`}, (err) => {
if (err) {
return console.log('file was not sent: ', err);
}
console.log('file was sent');
});
});
app.use('/media/:file', async (req, res) => {
res.sendFile(req.params.file, {root: `./src/media`}, (err) => {
if (err) {
return console.log('file was not sent: ', err);
}
console.log('file was sent');
});
});
the client img:
<img alt='unexpected reponse!!' src='http://127.0.0.1:2000/media/venego.jpeg'></img>
<img alt='unexpected reponse!!' src='http://127.0.0.1:2000/media/venego.jpeg'></img>
Idk if this is enough though the way I'm able to get it to work: I get the img from the server using fetch
export const readBlob = (route) =>
fetch('http://127.0.0.1:2000/' + route)
.then(async (res) => {
return URL.createObjectURL(await res.blob());
})
.catch((err) => err);
export const readBlob = (route) =>
fetch('http://127.0.0.1:2000/' + route)
.then(async (res) => {
return URL.createObjectURL(await res.blob());
})
.catch((err) => err);
<img
src=''
onClick={(e) => {
(async () => {
const response = await readBlob('media/venego.jpeg');
console.log(response);
e.target.src = response;
})();
}}
></img>;
<img
src=''
onClick={(e) => {
(async () => {
const response = await readBlob('media/venego.jpeg');
console.log(response);
e.target.src = response;
})();
}}
></img>;
I think since the second way is able to get the img... the way img handles the response is the thing causes the problem and what I should understand. or maybe is the way I send the file from the server is different from what img expects?
venego
venegoOP•2y ago
turns out img tag by default doesn't know about CORS
Ambushfall
Ambushfall•2y ago
I see, can't say I've noticed any issues pulling up any img elements using t3. Happy that it's resolved.
venego
venegoOP•2y ago
interesting, I think I should try t3. thank you for your efforts
Ambushfall
Ambushfall•2y ago
Op, sorry to bother you on such late notice, but take a look at this, might assist a tad bit https://discord.com/channels/966627436387266600/1044372514199052338 Cheers!
venego
venegoOP•2y ago
not bothering me at all. but it's kind of unrelated to my error. the actual problem was with the way img tag was designed by default. https://www.dofactory.com/html/img/crossorigin#:~:text=The%20crossorigin%20attribute%20on%20an,retrieve%20files%20from%20other%20domains. I need to explicitly tell it to be aware of CORS. using the crossorigin attribure. @lukacolic
Ambushfall
Ambushfall•2y ago
It seems like you don't actually own the API, in which case my previous answer would make more sense, nevertheless it got fixed. This article from Mozilla pretty much sums up how HTTP Handles CORS https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
Cross-Origin Resource Sharing (CORS) - HTTP | MDN
Cross-Origin Resource Sharing (CORS) is an HTTP-header based mechanism that allows a server to indicate any origins (domain, scheme, or port) other than its own from which a browser should permit loading resources. CORS also relies on a mechanism by which browsers make a "preflight" request to the server hosting the cross-origin resource, in ord...
venego
venegoOP•2y ago
I know how CORS work. however I found this from the link you shared: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/img-src does this mean I should specify some kind of header related to images?
CSP: img-src - HTTP | MDN
The HTTP Content-Security-Policy img-src directive specifies valid sources of images and favicons.
Ambushfall
Ambushfall•2y ago
This defines your source of resources allowed to be visible, on the client side, basically limits the src to match the domain otherwise all other requests would fail.
venego
venegoOP•2y ago
ok I kind of get it now. so how do I setup my API to allow src to fetch data from other routes?
venego
venegoOP•2y ago
is this package related to what I'm trying to do? https://www.npmjs.com/package/express-csp-header
npm
express-csp-header
Content-Security-Policy middleware for Express. Latest version: 5.1.0, last published: 8 months ago. Start using express-csp-header in your project by running npm i express-csp-header. There are 7 other projects in the npm registry using express-csp-header.
venego
venegoOP•2y ago
I've tried this:
res.set('Content-Security-Policy', 'img-src "127.0.0.1:2000/media"');
res.sendFile(req.params.file, {root: `./src/media/${req.params.section}`}, (err) => {
if (err) {
return console.log('file was not sent: ', err);
}
console.log('file was sent');
});
res.set('Content-Security-Policy', 'img-src "127.0.0.1:2000/media"');
res.sendFile(req.params.file, {root: `./src/media/${req.params.section}`}, (err) => {
if (err) {
return console.log('file was not sent: ', err);
}
console.log('file was sent');
});
but still...
Ambushfall
Ambushfall•2y ago
You're able to use the CSP Middleware to filter out who will be able to request the images and from what Origin Basically, wrap the invocation with the middleware I've found the perfect doc for your usage.
Ambushfall
Ambushfall•2y ago
Make sure to take precaution to reject requests from other sources other than the one you want accessing it to avoid spam.
venego
venegoOP•2y ago
but this doesn't say anything about img. this is just a basic cors setup which is the reason why I'm able to fetch the image using fetch in the first place. it's not the perfect doc, it's the abcd's of setting up an express server. but I need to understand more than that
Ambushfall
Ambushfall•2y ago
Servers don't really look at HTML elements, they see you've requested a resource with a GET request, and if you're authorized they serve it. To help you any further I'd have to have some sort of code to test this with in order to replicate it, as for me it works fine, no matter what.
venego
venegoOP•2y ago
I know that my server setup is very basic. node, express, cors, helmet I think I'll just stick to crossorigin thanks tho I think there is some miscommunication here. you keep suggesting stuff that is more shallower than what I need each time you post something. nevertheless. my problem has been fixed.
Ambushfall
Ambushfall•2y ago
That's the only important part 😄
venego
venegoOP•2y ago
then you are wrong + you didn't even read what I wrote
Ambushfall
Ambushfall•2y ago
I've replied to "Problem has been fixed" I've got no issues attaching Img tags and reading them from other domains without crossorigin tags, next or otherwise. As you're unable to provide an example, I'm unable to replicate the issue. Within your provided code snippets, I've managed to get it working without issues
venego
venegoOP•2y ago
you've replied with an irrelevant reply, yes. which makes me wonder if you are trying to convey some stuff. (you know what I mean) I provided the minimal reproducible example, my theory is that you are trying it with an extra setup.
Want results from more Discord servers?
Add your server