窗户,打开标题

我可以控制由 window.open(跨浏览器)发送的 HTTP 头吗?

如果没有,我可以以某种方式 window.open一个页面,然后发出我的请求与自定义标题内的弹出窗口?

我需要一些狡猾的黑客。

144419 次浏览

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.

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 :)

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
}

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')

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" action="###/your_page###" style="display:none">
<inputtype="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.

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

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.