Send a cross-domain request to log data - javascript

I'm working on an ad platform. When someone clicks on an image, I want to send a request back to my server to log this action. I have a pre-generated url for this. If I send a request to this url, it will log the data.
My issue is that the log url is on my domain, whereas the javascript is being executed in a client's domain. Without modifying the logging php script (to add something like Access-Control-Allow-Origin: *), is there a way to send this request to the new domain?
Since I'm only logging data, the server only sends back the text "OK" (which is information I don't need).

You should be able to send Ajax HTTP requests to any domain. I don't see what the problem is... It's the response that is restricted with the Same Origin Policy, not the request itself. You cannot access the response of the PHP script if the domains don't match, but the server will process the request normally, even if it's from a different domain.

This is a hack but it's commonly used. On click append an image to the DOM with the src set to the logging URL. To be friendly, have the output from the logging URL be a 1x1 pixel image. You'll have to pass the parameters via a GET string but it will work.

Create any dynamic DOM element with source on your domain (image or iframe), append a logging data to a request.
var logData = function(data){
if(data === undefined){
return;
}
var img=document.createElement("img");
img.setAttribute('src', 'http://another.domain?'+data);
img.setAttribute('height', '1px');
img.setAttribute('width', '1px');
document.body.appendChild(img);}
Your log requests will now appear in IIS logs

Cross-domain script restrictions are enforced at the browser level as a security precaution, so there is not a simple code fix to work around them. However, you can look at JSONP (JSON with padding) as a starting point.

You could create a hidden iframe with the src attribute set to the logging URL. This is at least as ugly as the image approach listed above.

Related

uploading images - do they have domain name in them - chrome not sending session id

For testing I downloaded images from the net and uploaded using valum file upload in chrome...chrome is not sending session cookie along with these request header( I dont see that in the server side/though I see it on developer tool)...does chrome know that these images are from different domain . what is happening...Is there work around for this to pass the session id (as cookie). It is also happening in IE10 which makes me belive it is some standard. and not just a chrome issue. This problem is not there with firefox/safari/opera
It is fine when uploading to localhost. only when uploading to different server with domain name there is this problem leading to creating a new session for this.
Update:
I have added xhr.withCredentials = true still no use.
Also added on the server side to the upload url...
res.setHeader 'Access-Control-Allow-Origin', '*'
res.setHeader 'Access-Control-Allow-Credentials', true
I dont know how helpful this would be, because I would have already sent the upload file and response header will not of much help.
basically the problem is I don't have access to the session variable at the server side, since the session id/sid cookie is not coming back /I am not able to save some of this upload details into the current session(because this is a new session) .
Update:
I tried creating an image in teh desktop using paint..even then chrome would not sent the cookies. Really drives me crazy...
First of all, to get the basics out of the way, this is unrelated to the origin of the image. Chrome or other browsers don't care where you get your images.
It's rather difficult to guess exactly what's going on, would have helped to see a jsfiddle or some more setup explanation, but based on what I'm guessing, you might be using different domains for the page where the upload button is hosted and the target url where you're sending your files (even using ssl for one and http for the other makes it different). Even different subdomains will not allow cookies to be passed if the cookies were not set with a base domain (yourdomain.com)
So, if sub-domains are the problem, you know what to do - set a base domain so you get your cookies to go on any sub domain.
If it's http vs. https you need to always use https (or http) because you can't switch cookies between those two.
If that's not it, or if you're using completely different domains, you can access your cookies locally via script (if they're not marked as http only) and add them to the upload request. Valum 2.0 (don't know about v1.0) lets you add parameters to the request like so:
var uploader = new qq.FileUploader({
element: document.getElementById('file-uploader'),
action: '/server-side.upload',
// additional data to send, name-value pairs
params: {
param1: 'value1',
param2: 'value2'
}
});
You can't set cookies on a domain which is not the page's domain via script so for using completely different domains your only choice is using request params.
It is possible that the uploader is using Flash under some circumstances to do the upload. There is a bug in Flash which prevents cookies being sent for these types of requests. This would explain the behaviour you are seeing. The workaround is to pass in the sessionId and transmit it in a different way eg. querystring.

Make REST call in JavaScript without using JSON?

(extremely ignorant question, I freely admit)
I have a simple web page with a button and a label. When I click the button, I want to make a REST call to an entirely different domain (cross-domain, I know that much) and display the results (HTML) in the label.
With other APIs, I've played around with using JSON/P and adding a element on the fly, but this particular API doesn't support JSON so I'm not sure how to go about successfully getting through.
The code I have is:
function getESVData() {
$.get('http://www.esvapi.org/v2/rest/passageQuery?key=IP&passage=John+1', function (data) {
$('#bibleText').html(data);
app.showNotification("Note:", "Load performed.");
});
}
I get an "Access denied." Is there anyway to make this call successfully without JSON?
First off, JSON and JSONP are not the same. JSON is a way of representing information, and JSONP is a hack around the same-origin policy. JSONP works by requesting information from another domain, and that domain returns a script which calls a function (with the name you provided) with the information. You are indeed executing a script on your site that another domain gave to you, so you should trust this other domain.
Now when trying to make cross domain requests you basically have 3 options:
Use JSONP. This has limitations, including the fact that it only works for GET requests, and the server you are sending the request to has to support it.
Make a Cross Origin Resource Sharing (CORS) request. This also must be supported by the server you are sending the request to.
Set up a proxy on your own server. In this situation you set an endpoint on your site that simply relays requests. ie you request the information from your server, your server gets it from the other server and returns it to you.
For your situation, it the other server doesn't have support for other options, it seems like you will have to go with options 3.

Sending data to an external file via Ajax

When I use this code, it works:
ajax.open("post","a.php",true);
but when I try to send data to a external file like:
ajax.open("post","http://www.example.com/a.php",true);
it doesn't work.
Are there any solution?
The URL of the file that must be opened - the location of the server side script. This can be a absolute URL like(http://www.foo.com/bar.php) or a relative one(/bar.php). A note of caution - this URL should be in the same domain as the script is. You cannot call a script in google.com from a script that is running in yahoo.com. This is a security measure implemented in most browsers to prevent XSS.
Regards,
Cyril
On which domain is your script executed? Is it www.site.com or some other?
The reason your code might not work is because for security reasons you are not allowed to send AJAX request to other domains.
Edit: One workaround would be to implement a web service on mysite.com, send AJAX request to it. The service should then proxy the original request to othersite.com (server-side) and subsequently return the response to the script being executed on mysite.com.

Difference between localhost and IP address in Ajax request sending

I have a strange problem with native Ajax request invoking.
I am creating the Ajax object and sending the request like follows:
var xmlHttpObj = new XMLHttpRequest();
....
xmlHttpObj.open("GET","http://192.168.16.254:8080/ajax/demoExample.html",true);
xmlHttpObj.send();
When I access the servlet with the URL something like http://localhost:8080/ajax...,
then I am not able to get the response in the client side. But I can see the response in the server side.
Pretty similar way I invoked the request with
xmlHttpObj.open("GET","http://localhost:8080/ajax/demoExample.html",true);
and my URL is http://192.168.16.254:8080/ajax..., then also I am not able to see the response in my client side.
I know the best way to fix the problem.
I can invoke the request with
xmlHttpObj.open("GET","../ajax/demoExample.html",true);
xmlHttpObj.send();
then I don't have any problem with either localhost or IP address.
But still I think why is the difference between localhost and IP address in ajax requesting.
It's more of a security feature than a problem :
The same origin policy prevents a
document or script loaded from one
origin from getting or setting
properties of a document from another
origin.
localhost and 192.168.16.254 are considered different origins. The same goes for two hostnames that point to the same address as they could (and probably will) point to a different site/application on the same server. AFAIK the only way around this is to use iframe for content or JSONP for json. Although in your case relative URLs is the way to go.

A question about cross-domain (subdomain) ajax request

Let's say I have the main page loaded from http://www.example.com/index.html. On that page there is js code that makes an ajax request to http://n1.example.com//echo?message=hello. When the response is received a div on the main page is updated with the response body.
Will that work on all popular browsers?
Edit:
The obvious solution is to put a proxy in front of www.example.com and n1.example.com and set it so that every request going to a subresource of http://www.example.com/n1 gets proxied to http://n1.example.com/.
Cross domain is entirely a different subject. But cross sub-domain is relatively easy. All you need to do is to set the document.domain to be same in both the parent page and the iframe page.
document.domain = "yourdomain.com"
More info here
Note: this technique will only let you interact with iframes from parents of your domain. It does not alter the Origin sent by XMLHttpRequest.
All modern browsers support CORS and henceforth we should leverage this addition.
It works on simple handshaking technique were the 2 domains communicating trust each other by way of HTTP headers sent/received. This was long awaited as same origin policy was necessary to avoid XSS and other malicious attempts.
To initiate a cross-origin request, a browser sends the request with an Origin HTTP header. The value of this header is the site that served the page. For example, suppose a page on http://www.example-social-network.com attempts to access a user's data in online-personal-calendar.com. If the user's browser implements CORS, the following request header would be sent:
Origin: http://www.example-social-network.com
If online-personal-calendar.com allows the request, it sends an Access-Control-Allow-Origin header in its response. The value of the header indicates what origin sites are allowed. For example, a response to the previous request would contain the following:
Access-Control-Allow-Origin: http://www.example-social-network.com
If the server does not allow the cross-origin request, the browser will deliver an error to example-social-network.com page instead of the online-personal-calendar.com response.
To allow access to all pages, a server can send the following response header:
Access-Control-Allow-Origin: *
However, this might not be appropriate for situations in which security is a concern.
Very well explained here in below wiki page.
http://en.wikipedia.org/wiki/Cross-origin_resource_sharing
Another solution that may or may not work for you is to dynamically insert/remove script tags in your DOM that point to the target domain. This will work if the target returns json and supports a callback.
Function to handle the result:
<script type="text/javascript">
function foo(result) {
alert( result );
}
</script>
Instead of doing an AJAX request you would dynamically insert something like this:
<script type="text/javascript" src="http://n1.example.com/echo?callback=foo"></script>
Another workaround, is to direct the ajax request to a php (for example) page on your domain, and in that page make a cURL request to the subdomain.
The simplest solution I found was to create a php on your subdomain and include your original function file within it using a full path.
Example:
www.domain.com/ajax/this_is_where_the_php_is_called.php
Subdomain:
sub.domain.com
Create:
sub.domain.com/I_need_the_function.php
Inside I_need_the_function.php just use an include:
include_once("/server/path/public_html/ajax/this_is_where_the_php_is_called.php");
Now call sub.domain.com/I_need_the_function.php from your javascript.
var sub="";
switch(window.location.hostname)
{
case "www.domain.com":
sub = "/ajax/this_is_where_the_php_is_called.php";
break;
case "domain.com":
sub = "";
break;
default: ///your subdomain (or add more "case" 's)
sub = "/I_need_the_function.php";
}
xmlHttp.open("GET",sub,true);
The example is as simple as I can make it. You may want to use better formatted paths.
I hope this helps some one. Nothing messy here - and you are calling the original file, so any edits will apply to all functions.
New idea: if you want cross subdomain (www.domain.com and sub.domain.com) and you are working on apache. things can get a lot easier. if a subdomain actually is a subdirectory in public_html (sub.domain.com = www.domain.com/sub/. so if you have ajax.domain.com/?request=subject...you can do something like this: www.domain.com/ajax/?request=subject
works like a charm for me, and no stupid hacks, proxies or difficult things to do for just a few Ajax requests!
I wrote a solution for cross sub domain and its been working for my applications. I used iframe and setting document.domain="domain.com" on both sides. You can find my solution at :
https://github.com/emphaticsunshine/Cross-sub-domain-solution

Categories

Resources