36

Let's say I have a code like this:

<img src='images/whatever.jpj' width='' height=''/>

How to configure custom headers for this request?

Will appreciate any help.

Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
andrey
  • 1,867
  • 3
  • 21
  • 34
  • duplicate of [this](https://stackoverflow.com/questions/23609946/img-src-path-with-header-params-to-pass) – Paulo Jun 11 '18 at 05:00

5 Answers5

46

I'm late here, but you can do this with XMLHttpRequest and a blob.

var xhr = new XMLHttpRequest();
xhr.responseType = 'blob'; //so you can access the response like a normal URL
xhr.onreadystatechange = function () {
    if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
        var img = document.createElement('img');
        img.src = URL.createObjectURL(xhr.response); //create <img> with src set to the blob
        document.body.appendChild(img);
    }
};
xhr.open('GET', 'http://images.example.com/my_secure_image.png', true);
xhr.setRequestHeader('SecretPassword', 'password123');
xhr.send();

If you want, you could check to make sure the blob's MIME type is an image.

robbie
  • 1,219
  • 1
  • 11
  • 25
  • 2
    Thanks! It's never to late:) – andrey Mar 10 '17 at 17:45
  • @robbie0630 nailed it – Gandhi Jan 23 '18 at 13:36
  • @Paulo I did not copy that answer. Also, that solution hacks around with strings and btoa (and may break with some character encodings), while mine does it cleanly with a blob. Feel free to use whichever answer you see fit. – robbie Jun 11 '18 at 06:28
  • This works, however the browser will not cache it... Do u know how to cache it? – Apeiron Aug 07 '18 at 20:03
  • 1
    @Apeiron You can use the [Cache API](https://developers.google.com/web/fundamentals/instant-and-offline/web-storage/cache-api) with `Response` objects retrieved with the [Fetch API](https://developers.google.com/web/ilt/pwa/working-with-the-fetch-api). You may want to consider [using a service worker](https://developers.google.com/web/ilt/pwa/caching-files-with-service-worker) to transparently apply the cache to your app. HTH – robbie Jan 11 '19 at 01:55
  • 2
    Worth noting URL.revokeObjectURL() might want to use that too – Dmitry Minkovsky Sep 12 '20 at 18:19
15

Try (open console>networks> name: 200.jpg> RequestHeaders> hello: World!)

<img src onerror="fetch('https://picsum.photos/200',{headers: {hello:'World!'}}).then(r=>r.blob()).then(d=> this.src=window.URL.createObjectURL(d));" />
Kamil Kiełczewski
  • 85,173
  • 29
  • 368
  • 345
13

You cannot change the browser's HTTP request for resources loaded by the <img> tag. Whatever you are trying to do, you will need to find an alternative approach.

For example, you could proxy the request through your own server and modify the headers there. Or you could parametrise the URL of the resource with a query string.

As Alex points out, you may also be able to use an XmlHTTPRequest object to load the image data and use the setRequestHeader function, though I suspect you are limited in what headers you can set (I doubt you can spoof the referrer or user agent for example, though I haven't tested this).

Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
5

One alternative is to use cookie instead of header parameter.

If you want, for example, send a user credential to control the access to the image, this credential can be set to a cookie and this cookie can be validated at server side.

Pedro Leite
  • 566
  • 7
  • 3
  • But, per my trial, this method won't send the cookie values for image requests from the page where document.cookie is set. It will do so for future requests. Pl let know if this is not the case you observe. – Punit S Jan 18 '19 at 09:09
  • Good answer. @PunitS Images are loaded in the new request, after cookie is set. – ddur May 27 '20 at 23:28
5

This can be done using a service worker. In your service worker, handle the fetch event, and change the mode and headers of the request:

self.addEventListener('fetch', function(event) {
    const newRequest = new Request(event.request, {
        headers: {"Authorization": "Bearer XXX-my-token"},
        mode: "cors"
    });
    return fetch(newRequest);
}

It's important to change the mode from no-cors to cors, otherwise the header will silently be discarded.

Sjoerd
  • 74,049
  • 16
  • 131
  • 175