How to call REST service using JavaScript? - javascript

Using the code I found from one of the StackOverflow postings, I'm trying to call a REST service GET method. However, when the code runs it is not putting the GET format correctly in the URL.
Here's the code:
<!DOCTYPE html>
<script>
function UserAction(json)
{
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function ()
{
if (this.readyState == 4 && this.status == 200)
{
alert(this.responseText);
}
};
xhttp.open("GET", "http://localhost:8080/isJsonValid/json", true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send(json);
}
</script>
<form>
<button type="submit" onclick="UserAction(json)">Check if JSON Valid</button>
<label for="json">JSON:</label>
<input type="text" id="json" name="json"><br><br>
</form>
</html>
The expected format of this GET REST service would be:
http://localhost:8080/isJsonValid/json
(where json in the line above is the actual JSON sent as a parameter.)
Yet, what is shown in the URL line includes the project, directory and the URL has the ?name=value syntax.
Since the GET doesn't match the simple http://localhost:8080/isJsonValid/json format, I get a 404 error.
I realize there's something obvious I'm missing.
Thanks to all for suggestions.

If you need to send data you need to either send it as a query param or as the body. If you want to send it as a body need to use POST type. Below is the example of POST type.
// Create a request variable and assign a new XMLHttpRequest object to it.
var request = new XMLHttpRequest()
// Open a new connection, using the GET request on the URL endpoint
request.open('GET', 'https://ghibliapi.herokuapp.com/films', true)
request.onload = function() {
// Begin accessing JSON data here
var data = JSON.parse(this.response)
if (request.status >= 200 && request.status < 400) {
data.forEach(movie => {
console.log(movie.title)
})
} else {
console.log('error')
}
}
// Send request
request.send()
For post Request. As I don't have any API with me I have used get API URL.
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
console.log(this.responseText)
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
xhttp.open("POST", "https://ghibliapi.herokuapp.com/films", true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send("Your JSON Data Here");

Thanks all for the great input and help!
The best solution for me was to just use, as suggested, a POST. The GET was always putting the "?" in the URL even if I concatenated it, That "?" isn't how the REST service interprets the GET parameters so it wouldn't work that way. In the REST framework I'm using, GET parameters are just concatenated with one or more "/" as separators in the URL.
Appreciate all the terrific help here on SO. :)

Related

How do i put headers in an api call?

I am making an api call to
http(s)://{hostaddress:port}/com.broadsoft.xsi-actions/v2.0/user/{userid}/services/callcenter
I have changed the appropriate information in the URL to reflect the correct host address/port / user id.
When that is complete, the page requests that I log on with a Username and Password.
I can manually enter this information, and receive the XML that I need. This is not Ideal. I would rather have a form that passess in this information.
To my understanding, this information is passed within the "headers". I have tried to look up how to do this, and even attempted using postman without much luck. I am not sure how to do this.
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open("GET", "http(s)://{hostaddress:port}/com.broadsoft.xsi-actions/v2.0/user/{userid}/services/callcenter", true);
xhttp.send();
}
per w3 schools I can use setRequestHeader() which adds a label/value pair to the header to be sent.
I have tried
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
myFunction(this);
}
};
xhttp.open("GET", "http(s)://{hostaddress:port}/com.broadsoft.xsi-actions/v2.0/user/{userid}/services/callcenter", true);
xhttp.send();setRequestHeader(Username:myUserName,Password:myPassword);
}
with no resolution. once i get this working i will set up the form and pass in the values.
You are using setRequestHeader in the wrong way and calling send before setting headers in any case.
Try with
xhttp.setRequestHeader('Username', myUserName);
xhttp.setRequestHeader('Password', myPassword);
xhttp.send(); // only call send after setting up the headers
xhttp.setRequestHeaders(name, value) and it should be invoked before xhttp.send(). mdn

Send data on ajax

Is this the correct way to send data to server on ajax request?
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(response);
}
};
xhttp.open("GET", "https://myurl/", true);
xhttp.send(JSON.stringify("{ action: 'search', mode: question}"));
Because I get this error 405 (Method Not Allowed - Action not found)
No, there are several issues with that:
alert(response); will fail because there's no response variable; you'd probably want alert(xhttp.responseText).
You're doing a GET, but then trying to send a POST body. You can't do that. GET information is in the URL, not the body.
You're sending JSON (well, trying to), but not identifying it as JSON.
You're passing a string into JSON.stringify, where normally you'd pass an object, not a string, as its job is to convert things to JSON strings.
Assuming you mean to do a POST, and you really do want to send JSON (e.g., that the server is set up to accept JSON from the client), then minimal changes would be:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(xhttp.responseText); // 1
}
};
xhttp.open("POST", "https://myurl/", true); // 2
xhttp.setRequestHeader("Content-Type", "application/json"); // 3
xhttp.send(JSON.stringify({ action: 'search', mode: question})); // 4
Note that I'm assuming question is an in-scope variable in that.

Javascript HTTP POST with JSON data

Can I send a request as below? With parameters being assigned with a JSON style object. I only get error. But when I use a REST client and choose RAW data, it's OK. I guess I must have written incorrect code. How to send raw JSON data in JavaScript? Could anyone help me?
xmlhttp = new XMLHttpRequest();
var url = "https://someURL";
xmlhttp.open("POST", url, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.onreadystatechange = function () { //Call a function when the state changes.
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert(xmlhttp.responseText);
}
}
var parameters = {
"username": "myname",
"password": "mypass"
};
// Neither was accepted when I set with parameters="username=myname"+"&password=mypass" as the server may not accept that
xmlhttp.send(parameters);
No. The send() method can take a number of different argument types, but a plain object is not one of them (so it will probably end up having toString() being called on it and being turned into "[Object object]").
If you want to send JSON then you must:
Say you are sending JSON: xmlhttp.setRequestHeader("Content-type", "application/json");
Convert your JavaScript object to a string of JSON text: var parameters = JSON.stringify({"username":"myname","password":"mypass"});
Be prepared to accept JSON instead of application/x-www-form-urlencoded data on the server side.
Also note that, since you are using an absolute URI, you may run into cross domain issues.
xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", AjaxURL, true);
xmlhttp.onreadystatechange = function () { //Call a function when the state changes.
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
cb(xmlhttp.responseText);
}
};
xmlhttp.send(JSON.stringify(Idata));

XMLHttpRequest alters text in UTF-8

While processing a huge XML client-side, got stuck with the following issue: some unicode characters are replaced with unreadable sequences, so server cannot parse that XML. Testing like this:
var text = new XMLSerializer().serializeToString(xmlNode);
console.log(text);
var req = new XMLHttpRequest();
req.open('POST', config.saveUrl, true);
req.overrideMimeType("application/xml; charset=UTF-8");
req.send(text);
Logging still shows the correct string:
<Language Self="Language/$ID/Czech" Name="$ID/Czech" SingleQuotes="‚‘" DoubleQuotes="„“" PrimaryLanguageName="$ID/Czech" SublanguageName="$ID/" Id="266" HyphenationVendor="Hunspell" SpellingVendor="Hunspell" />
While in the request (Chrome dev tools) and at server side it appears modified like this:
<Language Self="Language/$ID/Czech" Name="$ID/Czech" SingleQuotes="‚‘" DoubleQuotes="„“" PrimaryLanguageName="$ID/Czech" SublanguageName="$ID/" Id="266" HyphenationVendor="Hunspell" SpellingVendor="Hunspell" />
Original encoding of the XML file is UTF-8, too. Absolutely the same behavior when using jQuery.
Check that overrideMimeType use uppercase "UTF-8" or lowercase "utf-8"
Make sure that string before javascript calculation was in utf-8 (check page charset)
Use escape/encodeURIComponent/decodeURIComponent before send it to server and unescape it on server
Try application/x-www-form-urlencoded ans send xml like plain text
P.S. Modified string is in ISO-8859-15
It seems to do so.
I have here data json parameter that includes a string "Lääke" (finnish word), that i sent to server via ajax.
This did NOT work, server app did not receive 'ää' but '??':
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
status = this.responseText;
if (status === "OK") {
window.location.assign("ackok.html");
}
else {
window.location.assign("ackerror.html");
}
}
};
xhttp.open("POST", "ProcessOrderServlet?Action=new&Customer="+data, true);
xhttp.send();
This did work, server received 'ää':
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
status = this.responseText;
if (status === "OK") {
window.location.assign("ackok.html");
}
else {
//orderStatusElement[0].innerHTML = "<b>Palvelimella jokin meni vikaan. Yritä myöhemmin uudelleen </b>";
window.location.assign("ackerror.html");
}
}
};
xhttp.open("POST", "ProcessOrderServlet?Action=new&Customer="+data, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.send();

"XMLHttpRequest Exception 101" on nested AJAX queries

I'm doing an AJAX fetch of a binary file the I am parsing in javascript. (Quake 2 BSPs, if anyone cares.) The code to fetch and parse the initial file is working fine, and looks roughly like this:
function loadFile(url) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var parsed = parseFile(request.responseText);
}
};
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.setRequestHeader('Content-Type', 'text/plain');
request.send(null);
}
As I said, that works fine, and everything loads and parses correctly. However, the file also describes several secondary files (textures) that need to be retrieved as well, and so I've added an inner loop that should load and parse all of those files, like so:
function loadFile(url) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var parsed = parseFile(request.responseText);
for(var i = 0; i < parsed.files.length; ++i) {
loadSecondaryFile(parsed.files[i].url); // Request code here is identical to this function
}
}
};
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.setRequestHeader('Content-Type', 'text/plain');
request.send(null);
}
function loadSecondaryFile(url) {
var request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (request.readyState == 4 && request.status == 200) {
var parsed = parseSecondaryFile(request.responseText);
}
};
request.open('GET', url, true);
request.overrideMimeType('text/plain; charset=x-user-defined');
request.setRequestHeader('Content-Type', 'text/plain');
request.send(null);
}
But every request made from within that loop immediately fails with the message (in Chrome, Dev Channel): NETWORK_ERR: XMLHttpRequest Exception 101 This strikes me as strange, since if I call loadSecondaryFile outside of loadFile it works perfectly.
My initial impression was that initiating an one ajax call in the onreadystatechage of another may be bad juju, but wrapping the secondary ajax calls in a setTimer doesn't make any difference.
Any ideas?
And... SUCCESS! So I feel really stupid, and I realize now that there's no way anyone else could have given me a solution with the information I presented. Terribly sorry!
It has nothing to do with AJAX and everything to do with how I was getting my URLs. Recall that I mentioned I was loading binary data from a Quake2 bsp, in this case, texture paths. Textures in the bsp format are stored as fixed length 32 bit strings with null padding. I was reading them using substr like so:
var path = fileBuffer.substr(fileOffset, 32);
Which I thought was giving me a string like "e2u3/clip", but in reality was giving me "e2u3/clip\0\0\0\0..." Of course, when printed this would look correct (since console.log represents the null char as nothing.) but the browser recognized it immediately as a bad URL and tossed it out.
Changing my read code to:
var path = fileBuffer.substr(fileOffset, 32).replace(/\0+$/,'');
Gives me valid strings and fixes all of my apparent AJAX problems! sigh
Thanks for all the suggestions! It helped put me on the right track.

Categories