Cookie not set with CORS Ajax request using XMLHttpRequest - javascript

I've been struggling about this for a while. We're calling our internal service via Ajax which will set a cookie after the request is done. From what I've seen so far this can be done via withCredentials parameter. I've also check the example from Mozilla
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials
Which points me to this. http://arunranga.com/examples/access-control/credentialedRequest.html
And it looks like it's working I just have to set the CORS correctly. However, when I copy the code and I tried calling my service I didn't see any cookie being set.
Here's the code.
var invocation = new XMLHttpRequest();
var url = 'MY SERVICE URL';
var invocationHistoryText;
function callOtherDomain(){
if(invocation)
{
invocation.open('GET', url, true);
invocation.withCredentials = "true";
invocation.onreadystatechange = handler;
invocation.send();
}
}
function handler(evtXHR)
{
if (invocation.readyState == 4)
{
if (invocation.status == 200)
{
var response = invocation.responseText;
console.log(response);
}
else
alert("Invocation Errors Occured" + invocation.readyState);
}
else
{
console.log("currently the application is at" + invocation.readyState);
}
}
This is the response I get
access-control-allow-credentials:true
access-control-allow-headers:Authorization, Content-Type, If-None-Match
access-control-allow-methods:GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS
access-control-allow-origin:http://localhost:8888
access-control-expose-headers:WWW-Authenticate, Server-Authorization
access-control-max-age:86400
cache-control:max-age=600
Connection:keep-alive
content-encoding:gzip
Content-Length:56
Content-Type:text/plain; charset=utf-8
Date:Thu, 07 Jul 2016 14:25:19 GMT
Expires:Thu, 07 Jul 2016 14:35:19 GMT
And this is the request header it makes
Request Headers
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8,th;q=0.6,zh-CN;q=0.4,zh-TW;q=0.2
Cache-Control:no-cache
Connection:keep-alive
Cookie:name=Fe26.2**6cff63f4eb1d5d63c9ef3beb4618b19b4638f5a805030ac9e3e06f0f3561e6f1*gX0LowRnJ-Bc0YS5WAMFqQ*66rp6okC9kDZXmZ4rl8BVVlGOI_KcGlydCG-XnFmgUX4_e6CMeg6JCpjx12xEF5c**a454d2b7be5b7f32cc463aaf151f67fbeefedf4dbe0d389ba2fb19a1b6745ba3*XBh9bkxi6HLcB0zwm500nYjsiiUw7TRsCZB_p2xgln4
DNT:1
Host:MY INTERNAL SERVICE
Origin:http://localhost:8888
Pragma:no-cache
Referer:http://localhost:8888/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36
So, I'm not sure what's wrong here.

Related

No HTTP response from Chrome extension to my Java Server

This is my very first question I am posting on StackOverflow. I usually tend to find answers to any question I have for whatever project, but I am really stuck on this one. I'm writing a Chrome extension that attempts to send JSON-objects over a HTTP post request with certain data in it to a basic Java server that will -in a later stage- process some of the data and return a HTTP response with relevant (processed) information for the client. This is the relevant JavaScript snippet on client-side:
function postRequest(jsonObject) {
var param = JSON.stringify(jsonObject);
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4) {
console.log(request.response);
}
};
request.open("POST", "http://"+link);
request.setRequestHeader("Content-type","text/plain");
request.send(param);
// request.abort();
}
The input JSON-object is legit and the link-item is the predefined host IP of the server. The server-side code is Java-based and is the following:
public class Server {
public static void main(String args[]) throws Exception {
while (true) {
try {
ServerSocket ss = new ServerSocket(1024);
Socket s = ss.accept();
System.out.println("Request: ");
BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter pw = new PrintWriter(s.getOutputStream());
String line;
while ((line = br.readLine()) != null) {
if (line.length() == 0) {
break;
}
System.out.print(line + "\r\n");
}
System.out.println("");
System.out.println("Response:");
String response = "HTTP/1.1 200 OK \r\n" + "Access-Control-Allow-Origin: * \r\n"
+ "Connection: close \r\n" + "\r\n";
System.out.println(response);
pw.write(response);
while ((line = br.readLine()) != null) {
if (line.length() == 0) {
break;
}
System.out.print(line + "\r\n");
}
br.close();
pw.close();
System.out.println("");
System.out.println("Socket Closed");
System.out.println("");
s.close();
ss.close();
} catch (Exception ex) {
// Do whatever
}
}
}}
The server does receive the request and the JSON-object, but no response is received on client side (readyState is usually 4, but status code is 0 and responseText is empty). Additionally the connection is not closed when I don't use request.abort() or close the extension's window. It for sure has nothing to do with the permissions in the manifest file, so I didn't include it in this post. Can somebody see what my mistake is or anybody have had a similar experience?
EDIT:
The HTTP request is received on server side and looks like:
POST / HTTP/1.1
Host: [IP address of the server; I deleted the exact address for privacy]
Connection: keep-alive
Content-Length: 173
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36
Origin: chrome-extension://nhpingbdjkkljheamibjobneeehiednk
Content-type: text/plain
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: nl-NL,nl;q=0.8,en-US;q=0.6,en;q=0.4,fr;q=0.2
Since the request is received on server side, I figured that the actual sending of the response is currently unsuccessful. Might it have something to do with the origin domain of the client? When I copy-paste that domain in my browser, I get a ERR_FILE_NOT_FOUND.

Websocket handshake doesnt work

i have a cpp server using WinSock2 and im trying to connect to this server with my javascript client, and it doesnt work, the chrome console says "Error during WebSocket handshake: Incorrect 'Sec-WebSocket-Accept' header value".
i compared my sha1 and base64 functions with online sha1 and base64 so the problem isnt here.
Chrome Response Header:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-Websocket-Accept: NzdkYjg1Y2I4MDRlNTk0OGNmNzI1NzdjZDgwOTEwZWZiYWI1NzQ3Yw==
Chrome Request Header:
GET ws://localhost:8820/ HTTP/1.1
Host: localhost:8820
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket
Origin: file://
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
Accept-Encoding: gzip, deflate, sdch, br
Accept-Language: he-IL,he;q=0.8,en-US;q=0.6,en;q=0.4
Sec-WebSocket-Key: Y7a2ZKEz/VCM92Wya49iPA==
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Server Code:
//key is already defined.
key += "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
key = sha1(key);
key = base64_encode(reinterpret_cast<const unsigned char*>(key.c_str()), key.length());
toClient = "HTTP/1.1 101 Switching Protocols\r\n";
toClient += "Upgrade: websocket\r\n";
toClient += "connection: Upgrade\r\n";
toClient += "Sec-Websocket-Accept: ";
toClient += key;
toClient += "\r\n\r\n";
sendData(sc, toClient);
Client Code:
<!DOCTYPE HTML>
<script type="text/javascript">
function WebSocketTest()
{
if ("WebSocket" in window)
{
//alert("WebSocket is supported by your Browser!");
// Let us open a web socket
var ws = new WebSocket("ws://localhost:8820");
console.log("test");
ws.onopen = function()
{
alert("Connection.")
// Web Socket is connected, send data using send()
ws.send("20304user04user04user");
//alert("Message is sent...");
};
ws.onmessage = function (evt)
{
var received_msg = evt.data;
alert("Hey");
};
ws.onclose = function()
{
// websocket is closed.
alert("Connection is closed...");
};
}
else
{
// The browser doesn't support WebSocket
alert("WebSocket NOT supported by your Browser!");
}
}
</script>
<div id="sse">
Run WebSocket
</div>
I tried manually to build the response:
Raw sha1 digest bytes of the concatenation are 77db85cb804e5948cf72577cd80910efbab5747c
Bytes to base 64: d9uFy4BOWUjPcld82AkQ77q1dHw=
This is different than what you have. You are transforming the hexadecimal string representation of those bytes to base 64 instead of raw bytes to base 64.

Why Javascript XMLHttpRequest octet-stream MIME type returns the response as string?

I tried to obtain gltf binary file with XMLHttpRequest. This is the code I tried.
var xhr = new XMLHttpRequest();
xhr.open("GET","THE ADDRESS",true);
xhr.setRequestHeader("Accept", "application/octet-stream");
xhr.responseType = "arraybuffer";
xhr.onload = function (v) {
resolve(xhr.response); // xhr.response must be ArrayBuffer but xhr.response is string
};
xhr.onerror = function (e) {
reject(e);
};
xhr.send();
As per the code above, I definitely set responseType as arraybuffer. But when the onload handler called, responseType field was changed as "".
I'm not calling any other ``XMLHttpRequest in this code. This is response header I got.
accept-ranges:bytes
content-length:102040
content-type:application/octet-stream
date:Fri, 18 Nov 2016 09:30:13 GMT
etag:"582ec3ef-18e98"
last-modified:Fri, 18 Nov 2016 09:03:43 GMT
server:h2o/2.0.4
status:200
And this is the request header I sent.
:authority:localhost
:method:GET
:path:/gex/t90-01/Duck/Duck.bin
:scheme:https
accept:*/*
accept-encoding:gzip, deflate, sdch, br
accept-language:ja,en-US;q=0.8,en;q=0.6
cache-control:no-cache
pragma:no-cache
referer:https://localhost/gex/
user-agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36
Anyt help?
You can try the below code by changing setRequestHeader with overrideMimeType as below.
And also, you should handle the xhr.response properly inside the resolve method you used below and not sure, you have done it correctly.
var xhr = new XMLHttpRequest();
xhr.open("GET","THE ADDRESS",true);
xhr.overrideMimeType("application/octet-stream");
//xhr.setRequestHeader("Accept", "application/octet-stream");
xhr.responseType = "arraybuffer";
xhr.onload = function (v) {
resolve(xhr.response); // xhr.response must be ArrayBuffer but xhr.response is string
};
xhr.onerror = function (e) {
reject(e);
};
xhr.send();

Want to display a PDF document returned by a GET request in IE11

This is something that I feel should be very simple, but haven't been able to solve so far.
I'm working with a vendor system which has implemented a very basic API for our use. We send a GET request with an authentication token in the header, the server then returns us a PDF document in the body of the response.
All I want to do is display the PDF in the browser, any method would be fine, in a new tab or iframe etc.
I have managed to get this working in both firefox and chrome utilising the answer at: Request a file with a custom header But this does not work with IE 11, and IE11 is the only supported browser within our organisation.
Request headers are:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Authorization:bearer ZYFXVEnE2Uf3kU0Ud8rFvq5pbV2IfrNzzJBAu8lI8p73reZ6-vdeChtXlGGN7NwUNvo2-5LKNd9FniZlcElplycBL4f2qu6EaHkO-Xb_-G5DR07p62UYq_DErl937Yc-mpLMphBBHC7-0uqYNfrivkbc3xeOvEBnRRtfagz7dYJ8EJive6QjwWjYgGj9HRQUAbcOggbJGxZDXmrlWTveUji-5CKb7w5guBUOhjyDkyB53r8rm2qptGfsp1NsKLU4h4kEDlNaxbbzB_oJQbuyIoG80BTnP-NB0bqOtPJ09FrM9AFVfrdJM0fRwS3BfxRgVNm01FgW-jQwp1GgzeAbS-3uRR1G92Y-rw6L8R17l31PPFlV_CNeK_oAG-AJldmn2lgv6a6l6Cj9s2OqOfXyX09iZIN6vIKXAqedSWb708GTNfJ7iLKjdGVYCYW1zZ9IZKXMyeMoK7nW_rDuMzmoXeLY3tGFeeOf27vuI4RdSaGVCD5kIynrYPe8fU1sp-KZE0i1aJ0qqQ9g7Nvg42ZsFIFHBqhRIY-k4Dxjm1jPloGNbFqhdc-GK5LYHcg_u3DwFbSUKWpXdzCPBn43qJ_yVfDqffQDsDafvGDKP0U4duq0eYNXYWKnB8VR7xytykWjXAj70a9SFPRocqhugiqJIwBMS6a5gfqlUssgEnCfhVGE_eGUSGrYdCvfHHKb-13O9m6dXomYFuK8Ql7H73MjDgzTihtYLULh3nAHrU-FehrBRsUeKpc32hKUVhVvTlw2lTOUcMhlC99EKPMT0hZhLy4t8e-icL2aqcKdN-S1rt-HU60cukw4SnLyM_Nfa-ytD8vtUwMLAV9K5h4DdK7H3LpfbQNbaHRfBjRk5aQ7Q2o
Content-type:application/json
Host: /vendor_URL/
Origin:null
Proxy-Connection:keep-alive
User-Agent:Mozilla/5.0 (Windows NT 6.3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36
Response Headers:
Accept-Ranges:none
Access-Control-Allow-Origin:*
Cache-Control:no-cache
Content-Disposition:inline; filename=GoToPlan.pdf
Content-Length:372483
Content-Type:application/pdf
Date:Wed, 26 Oct 2016 19:41:04 GMT
Expires:-1
Pragma:no-cache
Proxy-Connection:keep-alive
Server:Microsoft-IIS/7.5
Via:1.1 /proxy_URL/
X-AspNet-Version:4.0.30319
X-Powered-By:ASP.NET
Code that currently works in firefox and Chrome:
var document_http = new XMLHttpRequest();
var url = /document_URL/
document_http.open("GET", url, true);
//DOn'y know why, but needs this to display correctly
document_http.overrideMimeType( "application/octet-stream; charset=x-user-defined;" );
//Send the proper header information along with the request
document_http.setRequestHeader("Content-type", "application/json");
document_http.setRequestHeader("Authorization", "bearer " + auth_response[3]);
document_http.onreadystatechange = function() {//Call a function when the state changes.
if (document_http.readyState == 4 & document_http.status == 200) {
var data = toBinaryString(this.responseText);
data = "data:application/pdf;base64,"+btoa(data);
window.open(data);
}
}
document_http.send(params);
function toBinaryString(data) {
var ret = [];
var len = data.length;
var byte;
for (var i = 0; i < len; i++) {
byte=( data.charCodeAt(i) & 0xFF )>>> 0;
ret.push( String.fromCharCode(byte) );
}
return ret.join('');
}
Data URIs are subject to browsers' limitations on URLs. You can't reliably use them to display long content.
You can load the document as a blob, then use it in a iframe:
var xhr = new XMLHttpRequest();
xhr.open("GET", "/path/to/file.pdf");
xhr.responseType = "blob";
xhr.onload = function(res) {
iframe.src = URL.createObjectURL(res.response);
};
xhr.send();
This should work in every major browser. URL.createObjectURL will create a string of the form blob:http://host/unique-id that is a reference to the blob object.
Remember to call URL.revokeObjectURL on the given string when you're done showing the PDF. This will discard the reference to the blob, which can be safely garbage collected.

XMLHttpRequest lengthComputable always false

I need to AJAX load big binary files, hence I would like to show a progress indicator. I've read the lengthComputable field of the Progress.event parameter is true when there'sa "Content-Length" header set. I have this header, but lengthComputable is always false. What I'm doing wrong?.
Here's the code:
function onProgress(evt){
if(evt.lengthComputable){
this.progress = (evt.loaded / evt.total)*100;
// do something ...
}
}
function load(url){
var me = this;
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer';
xhr.onload = this.load;
xhr.onprogress = this.updateProgress;
xhr.send();
}
And this is the header (from Chrome):
Request URL:http://localhost/cgi-bin/test.cgi
Request Method:GET
Status Code:200 OK
Request Headersview source
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:es-419,es;q=0.8
Connection:keep-alive
Cookie:__utma=1.1581312881.1342448904.1342729430.1342812228.5
Host:localhost
Referer:http://localhost/cgi-bin/test.cgi
User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.35 (KHTML, like Gecko) Chrome/27.0.1448.0 Safari/537.35
Query String Parametersview sourceview URL encoded
idimage:3431
Response Headersview source
Connection:Keep-Alive
Content-Encoding:deflate
Content-Length:11825252
Content-Type:application/binaryfile
Date:Fri, 05 Apr 2013 11:36:06 GMT
Keep-Alive:timeout=5, max=98
Server:Apache/2.2.22 (FreeBSD) mod_ssl/2.2.22 OpenSSL/0.9.8x DAV/2 PHP/5.3.10 with Suhosin-Patch mod_python/3.3.1 Python/2.7.3 mod_perl/2.0.5 Perl/v5.10.1
EDIT: It looks like the problem is the Content-Encoding, in my case deflate: How can I use deflated/gzipped content with an XHR onProgress function?

Categories