97

Can I control the HTTP headers sent by window.open (cross browser)?

If not, can I somehow window.open a page that then issues my request with custom headers inside its popped-up window?

I need some cunning hacks.

Nakilon
  • 34,866
  • 14
  • 107
  • 142
Andrew Bullock
  • 36,616
  • 34
  • 155
  • 231
  • There is an open issue for adding support for headers to the window.open function in the HTML standard. Please voice your opinions and needs on there. [https://github.com/whatwg/html/issues/7810](https://github.com/whatwg/html/issues/7810) – Dan Apr 11 '22 at 21:00

7 Answers7

56

Can I control the HTTP headers sent by window.open (cross browser)?

No

If not, can I somehow window.open a page that then issues my request with custom headers inside its popped-up window?

  • You can request a URL that triggers a server side program which makes the request with arbitrary headers and then returns the response
  • You can run JavaScript (probably saying goodbye to Progressive Enhancement) that uses XHR to make the request with arbitrary headers (assuming the URL fits within the Same Origin Policy) and then process the result in JS.

I need some cunning hacks...

It might help if you described the problem instead of asking if possible solutions would work.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • 2
    Even with XHR there is limited support for header customization (http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader-method) – Free Consulting Dec 01 '10 at 16:43
  • @FreeConsulting link is actually: http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader%28%29-method – David Oct 18 '13 at 06:16
  • @sureshvv — No. You cannot control the headers sent there either. If it preserves login status that is because the login method doesn't use custom headers. – Quentin Dec 04 '20 at 07:53
  • 2
    No custom headers needed. Just basic auth. How do u pass that to window.open()? – sureshvv Dec 04 '20 at 08:29
  • You can't. The user will be prompted to enter their credentials when they visit the URL. The browser will then remember them for the session. – Quentin Dec 04 '20 at 08:43
  • @quentin ok.. i have job dashboard url within my .NET solution (so everything there is several web apps within one IIS site, including Identity server), which I access from Angular app (another web app). I am an authenticated user, however when I am redirected to dashboard url (via window.open, no other way, since it's a server page) - there is no any authentication info available. How am I supposed to get this authentication info? Of course I am not going to expose anything via URL. – Alexander Dec 30 '20 at 18:48
  • @Alexander - https://stackoverflow.com/questions/ask – Quentin Dec 30 '20 at 19:46
24

Sadly you can't control headers when doing window.open()

Nice and easy, how I managed to open a file with custom headers:

const viewFile = async (url) => {

  // Change this to use your HTTP client
      fetch(url, {/*YOUR CUSTOM HEADER*/} ) // FETCH BLOB FROM IT
        .then((response) => response.blob())
        .then((blob) => { // RETRIEVE THE BLOB AND CREATE LOCAL URL
          var _url = window.URL.createObjectURL(blob);
          window.open(_url, "_blank").focus(); // window.open + focus
      }).catch((err) => {
        console.log(err);
      });
};
  • Download file to cache
  • window.open to cache
Francky Vincent
  • 453
  • 4
  • 12
11

If you are in control of server side, it might be possible to set header value in query string and send it like that? That way you could parse it from query string if it's not found in the headers.

Just an idea... And you asked for a cunning hack :)

Igor
  • 3,054
  • 1
  • 22
  • 28
  • is n't adding a header in query string is susceptible to any security issues? since it is not going to be encrypted in https. – hashbytes May 23 '18 at 19:58
  • 3
    Querystrings ARE encrypted with https. https://stackoverflow.com/questions/2629222/are-querystring-parameters-secure-in-https-http-ssl But you still shouldn't put any sensitive info in query string... OP didn't specify what kind of headers they would like to put in query string. – Igor May 24 '18 at 10:23
0

As the best anwser have writed using XMLHttpResponse except window.open, and I make the abstracts-anwser as a instance.

The main Js file is download.js Download-JS

 // var download_url = window.BASE_URL+ "/waf/p1/download_rules";
    var download_url = window.BASE_URL+ "/waf/p1/download_logs_by_dt";
    function download33() {
        var sender_data = {"start_time":"2018-10-9", "end_time":"2018-10-17"};
        var x=new XMLHttpRequest();
        x.open("POST", download_url, true);
        x.setRequestHeader("Content-type","application/json");
//        x.setRequestHeader("Access-Control-Allow-Origin", "*");
        x.setRequestHeader("Authorization", "JWT " + localStorage.token );
        x.responseType = 'blob';
        x.onload=function(e){download(x.response, "test211.zip", "application/zip" ); }
        x.send( JSON.stringify(sender_data) ); // post-data
    }
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
actanble
  • 9
  • 2
-1

You can also use an F5 load balancer, and map the cross-browser URL that you are trying to fetch to an URL inside your domain of origin.

Mapping can be something like:

companyA.com/api/of/interest----> companyB.com/api/of/interest

Assuming your domain of origin is "companyA.com" then the browser will not have any problems in sending all cookies on the header of that request, since it's towards the same domain.

The request hits the load balancer and is forwarded towards "companyB.com" with all headers responses will be sent to the from server side.

Archit Gargi
  • 634
  • 1
  • 8
  • 24
otto
  • 161
  • 1
  • 1
  • 6
-4

You can't directly add custom headers with window.open() in popup window but to work that we have two possible solutions


  1. Write Ajax method to call that particular URL with headers in a separate HTML file and use that HTML as url in<i>window.open()</i> here is abc.html
        $.ajax({
        url: "ORIGIONAL_URL",
        type: 'GET',
        dataType: 'json',
        headers: {
            Authorization : 'Bearer ' + data.id_token,
            AuthorizationCheck : 'AccessCode ' +data.checkSum , 
            ContentType :'application/json'
        },

        success: function (result) {
              console.log(result);
        },
        error: function (error) {

        } });

call html

window.open('*\abc.html')

here CORS policy can block the request if CORS is not enabled in requested URL.


  1. You can request a URL that triggers a server-side program which makes the request with custom headers and then returns the response redirecting to that particular url.

Suppose in Java Servlet(/requestURL) we'll make this request

`

        String[] responseHeader= new String[2];
        responseHeader[0] = "Bearer " + id_token;
        responseHeader[1] = "AccessCode " + checkSum;

        String url = "ORIGIONAL_URL";

        URL obj = new URL(url);
        HttpURLConnection urlConnection = (HttpURLConnection) obj.openConnection();
        urlConnection.setRequestMethod("GET");
        urlConnection.setDoInput(true);
        urlConnection.setDoOutput(true);
        urlConnection.setRequestProperty("Content-Type", "application/json");
        urlConnection.setRequestProperty("Accept", "application/json");
        urlConnection.setRequestProperty("Authorization", responseHeader[0]);
        urlConnection.setRequestProperty("AuthorizationCheck", responseHeader[1]);
        int responseCode = urlConnection.getResponseCode();
        if (responseCode == HttpURLConnection.HTTP_OK) {
            BufferedReader in = new BufferedReader(new 
                         InputStreamReader(urlConnection.getInputStream()));
            String inputLine;
            StringBuffer response1 = new StringBuffer();

            while ((inputLine = in.readLine()) != null) {
                response1.append(inputLine);
            }
            in.close();
            response.sendRedirect(response1.toString());
            // print result
            System.out.println(response1.toString());
        } else {
            System.out.println("GET request not worked");
        }

`

call servlet in window.open('/requestURL')

-6

Use POST instead

Although it is easy to construct a GET query using window.open(), it's a bad idea (see below). One workaround is to create a form that submits a POST request. Like so:

<form id="helper" method="post" target="_blank" action="###/your_page###" style="display:none">
<input type="hidden" name="headerData" value="(default)">
</form>

<input type="button" onclick="loadNnextPage()" value="Click me!">

<script>
function loadNnextPage() {
  document.getElementById("helper").headerData.value = "New";
  document.getElementById("helper").submit();
}
</script>

Of course you will need something on the server side to handle this; as others have suggested you could create a "proxy" script that sends headers on your behalf and returns the results.

Problems with GET

  • Query strings get stored in browser history,
  • can be shoulder-surfed
  • copy-pasted,
  • and often you don't want it to be easy to "refresh" the same transaction.
Mike
  • 741
  • 13
  • 40
Artelius
  • 48,337
  • 13
  • 89
  • 105