How to make a cross domain http get request using javascript? - javascript

I'm trying to implement sms functionality in Dynamics CRM 2011. I've created a custom activity for this and added a button to the form of an SMS. When hitting the button, a sms should be send.
I need to make an http request for this and pass a few parameters. Here's the code triggered:
function send() {
var mygetrequest = new ajaxRequest()
mygetrequest.onreadystatechange = function () {
if (mygetrequest.readyState == 4) {
if (mygetrequest.status == 200 || window.location.href.indexOf("http") == -1) {
//document.getElementById("result").innerHTML = mygetrequest.responseText
alert(mygetrequest.responseText);
}
else {
alert("An error has occured making the request")
}
}
}
var nichandle = "MT-1234";
var hash = "md5";
var passphrase = "[encryptedpassphrase]";
var number = "32497123456";
var content = "testing sms service";
mygetrequest.open("GET", "http://api.smsaction.be/push/?nichandle=" + nichandle + "&hash=" + hash + "&passphrase=" + passphrase + "&number=" + number + "&content=" + content, true)
mygetrequest.send(null)
}
function ajaxRequest() {
var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
if (window.ActiveXObject) { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
for (var i = 0; i < activexmodes.length; i++) {
try {
return new ActiveXObject(activexmodes[i])
}
catch (e) {
//suppress error
}
}
}
else if (window.XMLHttpRequest) // if Mozilla, Safari etc
return new XMLHttpRequest()
else
return false
}
I get the "access is denied error" on line:
mygetrequest.open("GET", "http://api.smsaction.be/push/?nichandle=" ......
Any help is appreciated.

The retrieving site has to approve cross domain AJAX requests. Usually, this is not the case.
You should contact smsaction.be or check their FAQ to see if they have any implementation in place.
Usually JSONP is used for cross domain requests, and this has to be implemented on both ends.
A good way to overcome this, is using your own site as a proxy. Do the AJAX requests to an script on your side, and let it do the call. In example PHP you can use cURL

I suppose the SMS-service is in different domain. If so, you cannot make AJAX-call to it, because it violates same origin policy. Basically you have two choices:
Do the SMS-sending on server-side
Use JSONP
Also, is it really so that the passphrase and other secrets are visible in HTML? What prevents people from stealing it and using it for their own purposes?

Your AJAX requests by default will fail because of Same Origin Policy.
http://en.wikipedia.org/wiki/Same_origin_policy
Modern techniques allow CORS ( see artilce by Nicholas ) http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
jQuery's Ajax allow CORS.
Another way to do it is to get the contents and dynamically generate a script element and do an insertBefore on head.firstchild ( refer jQuery 1.6.4 source line no : 7833 )
Google analytics code does some thing similar as well. you might want to take a look at that too.
Cheers..
Sree

For your example, when requesting from different domain error is:
XMLHttpRequest cannot load http://api.smsaction.be/push/?nichandle=??????&hash=?????&passphrase=[???????????]&number=????????????&content=???????????????. Origin http://server is not allowed by Access-Control-Allow-Origin.
For cross domains XMLHttp requests destination server must send Access-Control-Allow-Origin response header.
MDN: https://developer.mozilla.org/en/http_access_control

Related

How to reading out XMLHttpRequest responses

I'm doing a XMLHttpRequest like this:
var url = "myurl.html";
var http_request=new XMLHttpRequest();
http_request.onreadystatechange=function(){
if (http_request.readyState === 4){
console.log(http_request.response);
}
};
http_request.withCredentials = true;
http_request.open('GET',url,true);
http_request.send(null);
In the console http_request.response is empty but when I look in Chrome into the networks Tab I get this stuff
How do I get to this stuff from JavaScript?
The request comes from a different computer on the same network. The server at myurl.html doesn't allow "Access-Control-Allow-Origin". For this, in the header of the response must be something like this:
Access-Control-Allow-Origin: *
(* stands for wildcard)
When the header is lacking that information, Chrome will block the response in the JavaScript. Hence, the network tab will show the response but not the JS console. To bypass CORS in different browsers there are several methods. I used an extension from the Chrome web store for Chrome.
To further ensure that the request was done correctly, the callback function can be modified to this:
http_request.onreadystatechange = function () {
if(http_request.readyState === XMLHttpRequest.DONE && http_request.status === 200) {
console.log(http_request.responseText);
}
};
http_request.readyState should be 4, the status however should be 0 (even though in the Network tab it will appear as 200).

No login required but still I see Session Expired Response in JMeter

I am automating load tests using Jmeter, I have very simple page where I'm putting data into input fields and buttons clicks.
I see following response data:
function handleBack() { var programGroup = document.getElementById('programGroupName').value; if(programGroup == 'SE') { var url = $('#fundraiserPageURL').val();; var index = url.lastIndexOf('/'); if (index > 0) { newurl = url.substring(0, index); } var action = newurl + "/decodeCheckOutDetails.action"; encodeCheckoutFRHttpSession(action, 'backFormIdFR'); } }
Visit LLS.ORG
0
VISIT LLS.ORG
Sorry! the session expired, please try again.
Make sure to upgrade to latest JMeter version (JMeter 3.3 as of now) as looking into i.e. HTTP Cookie Manager GUI it appears you're sitting on the outdated version. Or at least make sure you use the following settings in order to comply with the RFC 6265:
Implementation: HC4CookieHandler
Policy: standard
along with HttpClient4 implementation in the HTTP Request Defaults.
Also double check you performed correlation of all dynamic values using suitable JMeter PostProcessors.

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

XML accessible from URL line but not from script

When I type a certain URL in FF, I get the XML returned displayed on the screen, so the web service is apparently working. However, when I try to access it from a local HTML document running JS, I get unexpected behavior. The returned code is "200 OK" but there's no text (or rather it's an empty string) nor xml (it's null) in the response sections according to FireBug.
This is how I make the call.
var httpObject = new XMLHttpRequest();
httpObject.open("GET", targetUrl, true);
httpObject.onreadystatechange = function () {
if (httpObject.readyState == 4) {
var responseText = httpObject.responseText;
var responseXml = httpObject.responseXML;
}
}
httpObject.send(null);
Why does it happen and how do I tackle it?
That may be an HTTP header problem (e.g. missing Accept header); observe the headers sent by FF (you can use Firebug for that) and try to replicate them in your script (setRequestHeader).
Otherwise, that may be a "same origin policy" problem.

Check if same origin policy applies

Is there a "safe" way to check if the same origin policy applies to an URL before actually trying to use ajax methods? Here is what I have:
function testSameOrigin(url) {
var loc = window.location,
a = document.createElement('a');
a.href = url;
return a.hostname == loc.hostname &&
a.port == loc.port &&
a.protocol == loc.protocol;
}
This sort of works, but it’s kind of a manual guess based on the wikipedia article. Is there a better way of pre-checking cross domain allowance? jQuery is OK to use.
Is there a "safe" way to check if the same origin policy applies to an URL before actually trying to use ajax methods? Here is what I have:
function testSameOrigin(url) {
var loc = window.location,
a = document.createElement('a');
a.href = url;
return a.hostname == loc.hostname &&
a.port == loc.port &&
a.protocol == loc.protocol;
}
This is a safe and reliable way of doing it, provided you are doing (or rather not doing) certain things.
This sort of works, but it’s kind of a manual guess based on the wikipedia article.
This should fully work under the "normal" circumstances. It will need to be modified if you are planning to use cross-domain scripting.
If you modify document.domain in your scripts, for example from "foo.example.com" and "bar.example.com" to "example.com" your testSameOrigin function would return false for "http://example.com", where in fact it should return true.
If you are planning on modifying document.domain, you can add simply add a check for that in your script.
If you are planning on using CORS (see the link above) to allow cross-domain communication, it will also return a false negative. But if you are using CORS, you will have a list of domains that you can communicate with, and you can add that list to this function as well.
Is there a better way of pre-checking cross domain allowance? jQuery is OK to use.
Probably not, although it may be worth mentioning that what you are seeing in the console from Steve's answer might be the "observer's dilemma" ... Those errors look like they are resulting from the console trying to inspect the other window, not necessarily from the script.
Assuming you're not messing with document.domain or using CORS, your original solution is probably better, as it doesn't need to make an extra request to determine whether the server is available or not. Even if you are doing some cross-domain scripting, modifying the function you have now to accommodate it is probably your best bet.
Interesting question! I searched around and couldn't find anything other than what you posted, but I did come across this when I was messing around with some test code. If you just want a simple way to test a URL without making a request, I'd do it the way you're doing it. If you don't care about making a request to test, you could try this:
Make a simple ajax request to whatever URL you want:
var ajaxRequest = $.ajax({
url: 'http://www.google.com',
async: false
});
which returns a jqXHR object, which you can then check:
ajaxRequest.isRejected(); // or...
ajaxRequest.isResolved();
Now, the only problem with this is that isRejected() will evaluate to true for every single case where the page doesn't load (i.e. 404 Not Found, etc.), but you can check the status code with:
ajaxRequest.status;
It looks like the above line will return 0 when you attempt to break the same origin policy, but it will return the appropriate error code (again, i.e. 404) in other cases.
So to wrap up, maybe you could try doing something like:
function testSameOrigin(testUrl) {
var ajaxRequest = $.ajax({
url: testUrl,
async: false
});
return ajaxRequest.isRejected() && ajaxRequest.status === 0;
}
Not a definitive answer by any means, but I hope it helps you figure out what you're looking for!
Try this solution as well.
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function sameOrigin(url) {
// test that a given url is a same-origin URL
// url could be relative or scheme relative or absolute
var host = window.document.location.host; // host + port
var protocol = window.document.location.protocol;
var srOrigin = '//' + host;
var origin = protocol + srOrigin;
// Allow absolute or scheme relative URLs to same origin
return (url === origin || url.slice(0, origin.length + 1) === origin + '/') ||
(url === srOrigin || url.slice(0, srOrigin.length + 1) === srOrigin + '/') ||
// or any other URL that isn't scheme relative or absolute i.e relative.
!(/^(\/\/|http:|https:).*/.test(url));
}
// if you want to check before you make a call
if (!csrfSafeMethod(data.type) && sameOrigin(data.url)) {
// ...
}
// or if you want to set csrf token
$.ajax({
beforeSend: function (xhr, settings) {
if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
xhr.setRequestHeader("X-CSRFToken", getCookie("csrftoken"));
}
}
});
Another way to execute cross domain script is using JSON-P.
You can also read this article.
Otherwise, the cross domain scripting is not allowed by the same origin policy.
Building off of Dagg Nabbit's answer, this seems a little more complete:
function sameOrigin(url) {
var loc = window.location, a = document.createElement('a')
a.href = url
return a.hostname === loc.hostname &&
a.port === loc.port &&
a.protocol === loc.protocol &&
loc.protocol !== 'file:'
}
Caveats I can think of:
doesn't take document.domain into account
doesn't take CORS into account
Doesn't work in IE7 (as mentioned by zanona)
Doesn't work in weird environments (like android) where you can access arbitrary file:// protocol paths (someone please verify this, the info about android might be outdated https://security.stackexchange.com/questions/25138/same-origin-policy-for-file-urls-in-android-browser)

Categories

Resources