I know how to make an HTTP request to my REST api from javascript using jQuery or XMLHttpRequest. What I want to do now is make the request without setting properties for the he
To build on lonesomeday's answer, here's how to actually do it.
function rawRequest(txt,cb) {
let x = new XMLHttpRequest(),
lines = txt.split("\n"),
methods = [
"GET",
"POST",
"PATCH",
"PUT",
"DELETE",
"HEAD",
"OPTIONS"
],
host, path, method, version, body = "", headers = {}
lines.forEach((x, i) => {
if(!x.includes(":")) {
let ind;
methods.forEach(m => {
let tmpIndex = x.indexOf(m);
if(tmpIndex > -1) {
if(!method) {
ind = tmpIndex;
let words = x.split(" ");
method = x.substring(
tmpIndex,
tmpIndex +
m.length
);
method = method && method.trim();
path = words.find((y, k) =>
y[0] === "/"
)
path = path && path.trim();
version = (
x
.replace(method, "")
.replace(path, "")
).trim();
}
}
});
} else {
let indexOfSemiColon = x.indexOf(":");
if(
indexOfSemiColon > 0 &&
indexOfSemiColon < x.length - 1
) {
let key = x.substring(
0,
indexOfSemiColon
).trim(),
value = x.substring(
indexOfSemiColon + 1
).trim();
headers[key] = value;
if(key.toLowerCase() == "host") {
host = value
}
}
}
});
let inds = []
txt.split(/\r?\n/).forEach((x,i)=>
x === ""
&& inds.push(i)
)
let afterTwoLineBreaksIndex;
inds.forEach((x,i) => {
if(
i < inds.length - 2 &&
inds[i] === "" &&
inds[i + 1] === ""
) {
afterTwoLineBreaksIndex = i + 1;
}
});
if(afterTwoLineBreaksIndex) {
body = txt.substring(
afterTwoLineBreaksIndex
)
}
x.onreadystatechange = () => {
if(x.readyState == 4 && x.status == 200) {
if(cb) cb(x.response);
}
}
if(host && path && method) {
x.open(
method,
"http://" //don't know how to differentiate between http & https, if some1 could help out would be greate
+ host
+ path
);
for(let k in headers) {
x.setRequestHeader(k, headers[k]);
}
x.send(body);
}
return {
headers,
body,
method,
host,
path,
version
} //for testing just return all the values we found
}
console.log(
rawRequest(`
GET /search?q=test HTTP/2
Host: www.bing.com
User-Agent: curl/7.54.0
Accept: */*`
),
rawRequest(`
GET /foo/bar HTTP/1.1
Host: example.org
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; fr; rv:1.9.2.8) Gecko/20100722 Firefox/3.6.8
Accept: */*
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
X-Requested-With: XMLHttpRequest
Referer: http://example.org/test
Cookie: foo=bar; lorem=ipsum;
`),
rawRequest(`
GET /myapi/myresource/1234 HTTP/1.1
Host: localhost:51127
Content-Type: application/x-www-form-urlencoded
Accept: application/json, text/csv
Authorization: Basic <base64 encoded credentials>
`)
)
You can possibly get an instance of the HmlHttpRequest object and use the setRequestHeader.
jQuery has a beforeSend handler you can set to get the actual hxr object.
$.ajax({
beforeSend: function(xhr){
xhr.setRequestHeader("name","value");
}
...
})
There is no socket support in Javascript. You can only build HTTP queries by using the XMLHTTPRequest
wrapper, or optionally wrappers for that such as jQuery.ajax
. This is for all kinds of good reasons, principally security.
Came here looking for same thing. I think it would be possible to build something which takes a raw request text and parses that to an xmlHttpRequest object putting the headers etc in the correct properties. Pls comment a link if something like this already exists. Basically if jQuery has a function to BuildRequestFromRaw(text) that would be awesome.