Append something always to an XHR Request - javascript

I want to attach a JS Variable to every XHR request that will be issued from my single page web application.
What would be the best approach to achieve this? I don't want to establish special methods for sending with this attributes, as there may be third parties integrating with my application.
I thought about overriding the send method on the XHR Object but thats not considered good style either.
I can't use cookies due to requests being cross-domain.
Any better idea or approach to this?
Thank you!
-Alessandro

if you really want to extend the existing functionalities without adding any library-like function, you could solve this using monkey patching:
(function() {
var originalOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
var getParameter = 'foo=bar';
if(url.indexOf('?') === -1) {
url = url + '?' + getParameter;
} else {
url = url + '&' + getParameter;
}
console.log('you just got monkey-patched! url is now:', url);
originalOpen.call(this, method, url, async, user, password);
}
})();
var request = new XMLHttpRequest();
request.open('get', 'http://google.com');
see also this jsfiddle for a working example.
you can use the same technique when injecting stuff into the body of a request if you patch the send() function.
if you do, ensure you take care for the type of the data to be transmitted (see MDN). it doesn't make sense to append a parameter to a binary body ;)

Related

Understanding of ajax complete call

I'm struggling with stabilizing Selenium automation for jQuery/AJAX application hence referred to
https://www.swtestacademy.com/selenium-wait-javascript-angular-ajax/
and it has ajaxComplete() method which has following code -
var callback = arguments[arguments.length - 1];
var xhr = new XMLHttpRequest();
xhr.open('GET', '/Ajax_call', true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr.responseText);
}
};
xhr.send();
);
I haven't work on JavaScript before and this code which I'm not able to understand completely. I've following questions with this, if someone can help to understand it -
What is Ajax_call in this? Is it generic call to check ajax completion? Or do I need to have my own endpoint there? If yes, does single end point enough or do I need to identify all calls and add them in the method?
Please check the documentation for XMLHttpRequest.open. If you do, you will the second argument listed is
url
A DOMString representing the URL to send the request to.
This means that it is simply the URL you want to request. I can be anything you want. The / prefix means that you are request relative to the root of the website (so if you are requesting from https://example.com/somedir/somepage the request will be made to https://example.com/Ajax_call.

Redirecting XMLHTTP request - Javascript

I have a web page that has a too much content and javascript. When the page loads it makes multiple requests using Ajax and XMLHttp to load data. Is there a way to hook up all these requests and direct them to a different server.
For example the webpage fetches data from www.apple.com/data and www.mango.com/data after it is loaded. Is is possible to insert a script somewhere in the webpage which automatically changes any request made to www.orange.com/data.
Waiting for answer. Thanks
You can add a global handler to the ajaxSend event, the event will be triggered right before the ajax request being sent out. So you can check the request uri, apply some filtering logic, and then redirect the request by abort the original and resend it.
Below is an example
$(document).ajaxSend(function(e, xhr, opt) {
if (opt.url.indexOf("www.apple.com") !== -1) {
// abort the request
xhr.abort();
// change the uri to www.orange.com
opt.url = opt.url.replace("www.apple.com", "www.orange.com");
$.ajax(opt);
}
});
Ok. So I followed Anthony C's answer and it did actually work. But the problem with his solution is that it only works with Ajax requests not XMLHttpRequests (I am not sure why, I am a beginner at this topic.) However digging on his idea of creating a hook I came across a similar post here How to get the URL of a xmlhttp request (AJAX). The code provided a way to fetch the requested URL for each request. So by a little tweak to the code I managed to come up with this:-
XMLHttpRequest.prototype.open = (function(open) {
return function(method,url,async) {
var uri=getLocation(url);// use get location function to convert requested url string into readable url
if(uri.hostname!="orange.com"){
url="https://orange.com" + url;
}
open.apply(this,arguments);
};
})(XMLHttpRequest.prototype.open);
var getLocation = function(href) {
var l = document.createElement("a");
l.href = href;
return l;
};
This code at top of the page allows me to change the host name of all XMLHttpRequests that are not directed towards orange.com. Though I am sure there are better ways to write this code as well but since I am not an expert over javascript this will suffice my need for the time.

post http request to 3rd party server and get response with redirect

I have asp.net mvc project with form I need to send as httpRequestObject.
I'm trying for few days already to make simple XMLhttp request to 3rd party Credit card clearing company url and get back the response with redirect which on XML format - I don't care if redirection made by iframe or popup
checked all over the internet for solutions, tried it on JavaScript - but as far as I understood I'm not able to do it with JS, tried asp.net and c# also but nothing works for me.
checked all solutions here but still nothing work.
checked if I'm blocked in any way like proxy or firewall, and it's not the issue.
My current JS code is -
function createMPITransaction() {
var terminal_id = "0962832";
var merchant_id = "938";
var user = "my-user";
var password = "my-password";
var url="https://cguat2.creditguard.co.il/xpo/Relay";
var xmlStr = "my string";
var http = new XMLHttpRequest();
http.open("POST",url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader('Access-Control-Allow-Headers', '*');
http.setRequestHeader('withCredentials', true);
http.setRequestHeader('responseType', 'text');
var response = http.responseText;
http.onreadystatechange = function () {//Call a function when the state changes.
if (http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
console.log(xmlStr);
console.log(http);
http.send(xmlStr);
and getting this from console -
XMLHttpRequest {readyState: 1, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, responseURL: ""…}
Am I be able to do it on JS?
If not, how could I do it on asp.net c#?
the limitation of request to 3rd party server, and get redirection is not common and make it real challenge.
As far as just the code for redirection is concerned, you can look at similar answer, like for example: https://stackoverflow.com/a/3836811/6298965
What you may be still missing is to check if your request is specification compliant or you're actually getting an error so you're not redirected.
After an initial analysis, I guess that a jsonxml is likely needed for the api call.
Moreover it'd be better if you use or at least look at a github implementation: https://github.com/mderazon/creditguard-node/blob/master/lib/creditguard.js

Bitly API - how to shorten a link with pure javascript, no libraries available (not even jquery)

Below is working code to use jquery+javascript with Bitly's API to shorten a link (when you have a Bitly account with a login and API key).
My question is, how can I produce the exact same result using only pure javascript with no other libraries available?
Thank you very much to anybody who can help me out.
EDIT:
This question does not already have an answer (the recommended answer is not relevant at all) due to how specific this is. Also, no references to DOM are possible as this is for server-side code. Therefore every single answer in the suggested duplicate question will not work. Please do not mark this as duplicate.
I believe the way to do this is with an xmlhttprequest, but I have absolutely no idea how...
Thanks again.
var login = "LOGIN_HERE";
var api_key = "API_KEY_HERE";
var long_url = "http://www.kozlenko.info";
$.getJSON(
"http://api.bitly.com/v3/shorten?callback=?",
{
"format": "json",
"apiKey": api_key,
"login": login,
"longUrl": long_url
},
function(response)
{
alert('Shortened link is: ' + response.data.url);
}
);
Javascript libraries use the XMLHttpRequest object to make ajax calls. You could make the calls using this object. I quickly googled one up:
var xmlhttp = new XMLHttpRequest();
var url = "buildTheURLHere.com";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var jsonObj = JSON.parse(xmlhttp.responseText);
alert('Shortened link is: ' + jsonObj.url);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
Sources:
http://www.w3schools.com/json/json_http.asp
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
But are you actually talking about node.js? You mention something about server-side code in your post. If so, http.request would be your best bet.
Nodejs:
http://nodejs.org/api/http.html#http_http_request_options_callback
How to make external HTTP requests with Node.js

Javascript: xmlhttprequest randomly stuck at Ready State 1

I've been working on a Windows gadget (meaning the "browser" is Internet Explorer) that queries specified subnet addresses for information. Now, it sometimes does this at a relatively quick pace (roughly every 5 seconds) and it works well enough. However, sometimes it will get stuck at ready state 1 and will just stay there forever. Whenever the gadget tries to redo the function for getting the xmlhttprequest and getting information from it it will stay at state 1. This is easily replicable when opening multiple instances of the gadget and then closing all but one of them. At that point, the one that's still open will almost always get stuck in this state. I feel like it might have something to do with them all accessing the same website, or it may just have to do with xmlhttprequests being stopped mid-transmission and that preventing another from working. Below is the relevant code.
//Reference to this for the inner function
var me = this;
var request = new XMLHttpRequest();
request.onreadystatechange = onReadyStateChange;
var url = this.url;
//Make the URL random to prevent being cached
url += ("&a=" + ((new Date()).getTime()));
Trace(DEBUG_COMM, "Sase.updateStatus url: " + url);
request.open("GET", url, true);
request.send(); // fire off the request, calls httpRequestReadyStateChange as things continue
Trace(DEBUG_COMM, "Request sent" + request.readyState);
function onReadyStateChange() {Trace(DEBUG_COMM, "Sase.httpRequestReadyStateChange: state=" + request.readyState);
if (4 == request.readyState) {
Trace(DEBUG_COMM, "Sase.httpRequestReadyStateChange: status=" + request.status);
if (request.status == 200) {
Trace(DEBUG_COMM, "retrieved html: " + request.responseText);
var results = request.responseText;
var resultsString = request.responseText.toString();
Trace(DEBUG_COMM, "results String: " + resultsString);
me.ParseStatusData(resultsString);
}
else {
//me.commError(request.status);
}
request = null;
}
}
Well it looks like I figured it out. I had a feeling it was an unresolved request, since it only happens when instances of it are closed (meaning that if one of them is closed while in communication with the server it stays in communication forever and no one else can access the server) and it appears that is the case. I made some modifications to the code in multiple areas and basically what it comes down to is when the gadget closes it makes sure to abort all of the requests. The requests are now instance variables (to allow for the aborting of them), but are still made new everytime they are needed.
For those who stumble across this and need a concrete code example, here you go.
I had the same problem and the solution was to re-use the XMLHttpRequest object, to ensure that any previous request was cancelled before initiating a new one. This won't work if you want to have multiple AJAX requests flying around but in my case triggering a new request meant that the last one was no longer needed.
All of the requests on my page went through the same XMLHttpRequest wrapper method which looked like this;
//Declare the XMLHttpRequest object to be re-used
var global_xHttpRequest = null;
function xmlHttpHandler(type, params, complete, postData) {
//Prevents an issue where previous requests get stuck and new ones then fail
if (global_xHttpRequest == null) {
global_xHttpRequest = new XMLHttpRequest();
} else {
global_xHttpRequest.abort();
}
//Parse out current URL
var baseURL = window.location.host;
var svc = "https://" + baseURL + "/processAction?";
var url = svc + params;
global_xHttpRequest.open(type, url, true);
//Add the callback
global_xHttpRequest.onreadystatechange = complete;
global_xHttpRequest.send(postData);
}
Which can be used like this:
xmlHttpHandler("GET", params, completeFnc);

Categories

Resources