How do I pass along variables with XMLHTTPRequest - javascript

How do I send variables to the server with XMLHTTPRequest? Would I just add them to the end of the URL of the GET request, like ?variable1=?variable2=, etc?
So more or less:
XMLHttpRequest("GET", "blahblah.psp?variable1=?" + var1 + "?variable2=" + var2, true)

If you want to pass variables to the server using GET that would be the way yes. Remember to escape (urlencode) them properly!
It is also possible to use POST, if you dont want your variables to be visible.
A complete sample would be:
var url = "bla.php";
var params = "somevariable=somevalue&anothervariable=anothervalue";
var http = new XMLHttpRequest();
http.open("GET", url+"?"+params, true);
http.onreadystatechange = function()
{
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(null);
To test this, (using PHP) you could var_dump $_GET to see what you retrieve.

Manually formatting the query string is fine for simple situations. But it can become tedious when there are many parameters.
You could write a simple utility function that handles building the query formatting for you.
function formatParams( params ){
return "?" + Object
.keys(params)
.map(function(key){
return key+"="+encodeURIComponent(params[key])
})
.join("&")
}
And you would use it this way to build a request.
var endpoint = "https://api.example.com/endpoint"
var params = {
a: 1,
b: 2,
c: 3
}
var url = endpoint + formatParams(params)
//=> "https://api.example.com/endpoint?a=1&b=2&c=3"
There are many utility functions available for manipulating URL's. If you have JQuery in your project you could give http://api.jquery.com/jquery.param/ a try.
It is similar to the above example function, but handles recursively serializing nested objects and arrays.

If you're allergic to string concatenation and don't need IE compatibility, you can use URL and URLSearchParams:
const target = new URL('https://example.com/endpoint');
const params = new URLSearchParams();
params.set('var1', 'foo');
params.set('var2', 'bar');
target.search = params.toString();
console.log(target);
Or to convert an entire object's worth of parameters:
const paramsObject = {
var1: 'foo',
var2: 'bar'
};
const target = new URL('https://example.com/endpoint');
target.search = new URLSearchParams(paramsObject).toString();
console.log(target);

The correct format for passing variables in a GET request is
?variable1=value1&variable2=value2&variable3=value3...
^ ---notice &--- ^
But essentially, you have the right idea.

Following is correct way:
xmlhttp.open("GET","getuser.php?fname="+abc ,true);

Yes that's the correct method to do it with a GET request.
However, please remember that multiple query string parameters should be separated with &
eg. ?variable1=value1&variable2=value2

How about?
function callHttpService(url, params){
// Assume params contains key/value request params
let queryStrings = '';
for(let key in params){
queryStrings += `${key}=${params[key]}&`
}
const fullUrl = `${url}?queryStrings`
//make http request with fullUrl
}

Related

how to pass multiple parameters to the web API?

I want to send something like this to API
/GetRegionsByParentIdAndRegionType?parentId=63&regionTypeEnum=5
This is the method I use
return Service.get("/GetRegionsByParentIdAndRegionType?parentId= & regionTypeEnum=" +params.parentId+ params.regionTypeId, (status, data) => {
callback(status, data);
});
I know this is wrong.
What is the right way to use it?
Use the URL constructor to create an instance of URL and then append the search parameters using URL.searchParams property.
Following snippet shows a simple example:
const url = new URL('https://example.com');
url.searchParams.append('parentId', 63);
url.searchParams.append('regionTypeEnum', 5);
console.log(url);
Alternatively, you could create an instance of URLSearchParams and then concatenate that with the URL string.
Following code snippet shows an example:
let str = '/GetRegionsByParentIdAndRegionType?';
const searchParams = new URLSearchParams();
searchParams.append('parentId', 63);
searchParams.append('regionTypeEnum', 5);
str += searchParams;
console.log(str);

Why I get only part of the URL from the HttpContext?

I use proxy to get recource from remote server.
Here is proxy class:
public class Proxy : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string url = context.Request["url"];
var request = (HttpWebRequest)WebRequest.Create(url);
request.UserAgent = context.Request.UserAgent;
request.ContentType = context.Request.ContentType;
request.Method = context.Request.HttpMethod;
request.ProtocolVersion = HttpVersion.Version11;
request.KeepAlive = false;
request.Timeout = 100000;
request.ReadWriteTimeout = 100000;
using (var response = request.GetResponse())
{
context.Response.ContentType = response.ContentType;
using (var responseStream = response.GetResponseStream())
{
if (responseStream == null) return;
responseStream.CopyTo(context.Response.OutputStream);
context.Response.OutputStream.Flush();
}
}
}
}
And here is my ajax call to remote service:
function wfs(layer) {
let dest_url = "https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS&MAXFEATURES=500&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=ns216630453:WW_MONITOR";
let proxy_url = "/localhost/Proxy.ashx?url=";
let url = proxy_url + dest_url;
var xhr = new XMLHttpRequest();
xhr.open('GET', url); // depricated-'/proxy.ashx?url='+
xhr.onload = function () {
if (xhr.status === 200) {
console.log("loader success");
} else {
console.log("loader fail");
}
},
xhr.send();
}
when wfs function is fired the ProcessRequest function in proxy class is triggered and value of the url variable is:
https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS
While I expect the value of url to be:
https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS&MAXFEATURES=500&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=ns216630453:WW_MONITOR
It seems that context.Request["url"] returns cuted value until first '&'.
Any idea why I get from context.Request["url"] only part of the url?
You need to encode your query param, because it doesn't contain characters that are safe for query parameters:
let url = "/localhost/Proxy.ashx?url=" + encodeURIComponent(dest_url);
To further explain, let's pretend we're a URL parser. Without the encoding, you'll see this string:
/localhost/Proxy.ashx?url=https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS&MAXFEATURES=500&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=ns216630453:WW_MONITOR
The parser will go through these steps as it visits the characters:
URL path: /localhost/Proxy.ashx
Query params starting: ?
Param name: url
Starting param value: =
(some of these next chars aren't valid, but I'll try my best!)
Param value:
https://www.mysited.com/geodata2055/service/mapagent.fcgi?SERVICE=WFS
Starting next param: &
Param name: MAXFEATURES
Starting param value: =
Param value: 500
...etc
So because it's encountering the & while scanning your string, it thinks parameters like MAXFEATURES are query parameters for your proxy request, not part of the url parameter passed to the proxy request. Therefore, when your proxy code runs, it's seeing only things up to that &.
Encoding the URL parameter will give you:
/localhost/Proxy.ashx?url=https%3A%2F%2Fwww.mysited.com%2Fgeodata2055%2Fservice%2Fmapagent.fcgi%3FSERVICE%3DWFS%26MAXFEATURES%3D500%26VERSION%3D1.0.0%26REQUEST%3DGetFeature%26TYPENAME%3Dns216630453%3AWW_MONITOR
With this, the parser now only see a url parameter passed to the proxy handler. When the proxy handler now parses the url parameter, it will decode it, giving you back your original dest_url
As a general rule of thumb, never just use string concatenation to build URLs; URLs aren't made up of strings, they're made up of URL-encoded strings.

Save JSONObject

what kind of object is this?
I am trying to craft mock data in order to test an application and this is how one of my fake data looks like. How can I save this mock data?
I could only thought of using the JSON.stringify function and copy the result to save as a string. Obviously, after I do that, I would have no access to the attribute of the original object.
Are there any ways I can write this JSONObject into a file and have access to its properties later??
JSON.stringify() returns a string. To make an object you can access properties of again, you'll need to pass that string through JSON.parse().
It's also worth noting that if the object you're saving has any functions in it, they will not be saved.
In your code obj is a javascript object
You can use blob (https://developer.mozilla.org/en-US/docs/Web/API/Blob) and HTML5 download API to do the required as:
var json = JSON.stringify(obj);
var blob = new Blob([json], {type: "application/json"});
var url = URL.createObjectURL(blob);
var a = document.createElement('a');
a.download = "mydata.json";
a.href = url;
a.textContent = "Download mydata.json";
You can load that data and access it properties later using and XMLHttpRequest GET request as:
function loadJSON(callback) {
var getobj = new XMLHttpRequest();
getobj.overrideMimeType("application/json");
getobj.open('GET', 'mydata.json', true); // Replace 'mydata' with the path to your file
getobj.onreadystatechange = function () {
if (getobj.readyState == 4 && getobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(getobj.responseText);
}
};
getobj.send(null);
}
loadJSON(function(response) {
// Parse JSON string into object
var savedData = JSON.parse(response);
});
Using local storage maybe.
localStorage.setItem("MYMockData", JSON.stringify(fakeData));
var fakeDataRetrived = JSON.parse(localStorage.getItem("MYMockData"));

XMLHttpRequest send JS Object

I'm trying to send an JS Object with an (POST) XMLHttpRequest, but I get no POST data in PHP.
This code worked before with an Ajax request, but i'm trying to get feedback from the server for an progressbar ( whitch is working fine now). That's why i've chagend to XMLHttpRequest.
The code:
var dataRows = {
'bewaarnaam': bewaarNaam,
rows: {}
};
$(".rows").each(function (i, obj) {
var row = $(obj);
var rowName = $(row).attr('name');
var chests = {};
$(".cv_chest", row).each(function (i2, obj2) {
chests[$(obj2).attr('id')] = {
'counter': $(obj2).attr('chest_counter'),
'height': $(obj2).attr('chest_height'),
'db_id': $(obj2).attr('db_id')
};
});
var top = $(row).css('top').replace("px", "");
var left = $(row).css('left').replace("px", "");
var rowData = {
'name': $(row).attr('name'),
'x': parseInt(left),
'y': (parseInt(top - 100)),
'rotation': rotation[$(row).attr('dir')],
'db_id': $(row).attr("db_id"),
'chests': chests
};
dataRows.rows[$(row).attr('id')] = rowData;
});
...
var xhr = new XMLHttpRequest();
xhr.open("POST", "{{ url('bewaarplaatsen/xhrTest/') }}", true);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send(dataRows);
So my question is rather simple... How can i send an object with an post through the XmlHttpRequest function?
Use JSON:
var xhr = new XMLHttpRequest();
xhr.open("POST", "{{ url('bewaarplaatsen/xhrTest/') }}", true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.send(JSON.stringify(dataRows));
EDIT:
You can also use newer fetch API, see Fetch: POST JSON data.
You can't. "An object" is a data structure that exists in memory and only makes sense to the program it is dealing with it.
You need to serialise the data (e.g. using the application/x-www-form-urlencoded format, or JSON, or XML, or a host of other choices) and send that instead.
If you are trying to send entire DOM elements (and it isn't clear what the data you are trying to send actually is) then serialising them would involve converting them to HTML or (and this would usually be the better option) a data structure that they represent.

Send multiple parameter in ajax request using javascript

So I want to use ajax request and I know how to use it.
But problem that i had that I want to pass parameters to request. So My first page had 4 parameter then I build url like this,
var url = "./ControllerServlet?PAGE_ID=BPCLA&ACTION=closeAssessment&SAVE_FLAG=true&closeReason="+closeReasonStr+"&closeCmt="+closeCmt;
but now parameter is increasing like now I have 20 more. So now building url like this going to be messy approach. Is there a better way to do this.
Here is my function where i am building URL in javascript function.
function closeAssessment() {
var closeReason = document.getElementById("SectionClousureReason");
var closeReasonStr = closeReason.options[closeReason.selectedIndex].value;
var closeCmt=document.getElementById("SectionCloseAssessmentCmt").value;
var url = "./ControllerServlet?PAGE_ID=BPCLA&ACTION=closeAssessment&SAVE_FLAG=true&closeReason="+closeReasonStr+"&closeCmt="+closeCmt;
ajaxRequest(url);
return;
}
edit:
As you ask here is my ajaxRequest function,
function ajaxRequest(url) {
strURL = url;
var xmlHttpRequest = false;
var self = this;
// Mozilla, Safari
if (window.XMLHttpRequest) {
self.xmlHttpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
self.xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
self.xmlHttpRequest.open("POST", strURL, true);
self.xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
self.xmlHttpRequest.onreadystatechange = function() {
if (self.xmlHttpRequest.readyState == 4) {
if (self.xmlHttpRequest.status == 200) {
var htmlString = self.xmlHttpRequest.responseText;
var parser = new DOMParser();
var responseDoc = parser.parseFromString(htmlString, "text/html");
window.close();
} else {
ajaxFailedCount++;
// Try for 1 min (temp fix for racing condition)
if (ajaxFailedCount < 1200) {window.setTimeout(function() {ajaxRequest(url)}, 50);}
else {alert("Refresh failed!")};
}
}
}
self.xmlHttpRequest.send(null);
}
You could make an object with the key/value pairs being what you want added to the URL.
var closeReason = document.getElementById("SectionClousureReason");
var params = {
PAGE_ID: 'BPCLA',
ACTION: 'closeAssessment',
SAVE_FLAG: 'true',
closeReasonStr: closeReason.options[closeReason.selectedIndex].value,
closeCmt: document.getElementById("SectionCloseAssessmentCmt").value
};
Then add them to the URL via a loop.
var url = "./ControllerServlet?";
var urlParams = Object.keys(params).map(function(key){
return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
}).join('&');
url += urlParams;
ajaxRequest(url);
Note: I added encodeURIComponent just to be safe.
EDIT: From your comment, it seems you want to submit a <form> but you want to use AJAX to do so. In that case, you can loop over the form elements and build the above params object.
var params = {
PAGE_ID: 'BPCLA',
ACTION: 'closeAssessment',
SAVE_FLAG: 'true'
};
var form = document.getElementById('yourForm'),
elem = form.elements;
for(var i = 0, len = elem.length; i < len; i++){
var x = elem[i];
params[x.name] = x.value;
}
Build up an object of your parameters and put them in the uri through a loop like this:
var values= {
page_id: 'BPCLA',
action: 'test'
},
uri_params = [],
uri = 'http://yoururl.com/file.php?';
for (var param in values) uri_params.push( encodeURIComponent( param ) + '=' + encodeURIComponent( values[ param ] ) );
uri = uri + uri_params.join( '&' );
console.log( uri );
Or consider using POST to transport your parameters, as many browsers have limitations on the query string.
Edit: you can also build yourself a function which traverses your form and builds up the values object for you so you don't have to do it manually.
Be aware however that anyone can inject custom url paramters simpy by appending form elements before submitting the form (by using the developer tools for example) so keep that in mind.
If you are using jQuery you can use .serializeArray() or have a look at this answer for a possible function you could use.

Categories

Resources