Simple AJAX test is not working [duplicate] - php

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The same origin policy
I wanted to make a community wiki regarding HTML/JS same-origin policies to hopefully help anyone searching for this topic. This is one of the most searched-for topics on SO and there is no consolidated wiki for it so here I go :)
The same origin policy prevents a
document or script loaded from one
origin from getting or setting
properties of a document from another
origin. This policy dates all the way
back to Netscape Navigator 2.0.
What are some of your favorite ways to go around same-origin policies?
Please keep examples verbose and preferably also link your sources.

The document.domain method
Method type: iframe.
Note that this is an iframe method that sets the value of document.domain to a suffix of the current domain. If it does so, the shorter domain is used for subsequent origin checks. For example, assume a script in the document at http://store.company.com/dir/other.html executes the following statement:
document.domain = "company.com";
After that statement executes, the page would pass the origin check with http://company.com/dir/page.html. However, by the same reasoning, company.com could not set document.domain to othercompany.com.
With this method, you would be allowed to exectue javascript from an iframe sourced on a subdomain on a page sourced on the main domain. This method is not suited for cross-domain resources as browsers like Firefox will not allow you to change the document.domain to a completely alien domain.
Source: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
The Cross-Origin Resource Sharing method
Method type: AJAX.
Cross-Origin Resource Sharing (CORS) is a W3C Working Draft that defines how the browser and server must communicate when accessing sources across origins. The basic idea behind CORS is to use custom HTTP headers to allow both the browser and the server to know enough about each other to determine if the request or response should succeed or fail.
For a simple request, one that uses either GET or POST with no custom headers and whose body is text/plain, the request is sent with an extra header called Origin. The Origin header contains the origin (protocol, domain name, and port) of the requesting page so that the server can easily determine whether or not it should serve a response. An example Origin header might look like this:
Origin: http://www.stackoverflow.com
If the server decides that the request should be allowed, it sends a Access-Control-Allow-Origin header echoing back the same origin that was sent or * if it’s a public resource. For example:
Access-Control-Allow-Origin: http://www.stackoverflow.com
If this header is missing, or the origins don’t match, then the browser disallows the request. If all is well, then the browser processes the request. Note that neither the requests nor responses include cookie information.
The Mozilla team suggests in their post about CORS that you should check for the existence of the withCredentials property to determine if the browser supports CORS via XHR. You can then couple with the existence of the XDomainRequest object to cover all browsers:
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
Note that for the CORS method to work, you need to have access to any type of server header mechanic and can't simply access any third-party resource.
Source: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
The window.postMessage method
Method type: iframe.
window.postMessage, when called, causes a MessageEvent to be dispatched at the target window when any pending script that must be executed completes (e.g. remaining event handlers if window.postMessage is called from an event handler, previously-set pending timeouts, etc.). The MessageEvent has the type message, a data property which is set to the string value of the first argument provided to window.postMessage, an origin property corresponding to the origin of the main document in the window calling window.postMessage at the time window.postMessage was called, and a source property which is the window from which window.postMessage is called.
To use window.postMessage, an event listener must be attached:
// Internet Explorer
window.attachEvent('onmessage',receiveMessage);
// Opera/Mozilla/Webkit
window.addEventListener("message", receiveMessage, false);
And a receiveMessage function must be declared:
function receiveMessage(event)
{
// do something with event.data;
}
The off-site iframe must also send events properly via postMessage:
<script>window.parent.postMessage('foo','*')</script>
Any window may access this method on any other window, at any time, regardless of the location of the document in the window, to send it a message. Consequently, any event listener used to receive messages must first check the identity of the sender of the message, using the origin and possibly source properties. This cannot be understated: Failure to check the origin and possibly source properties enables cross-site scripting attacks.
Source: https://developer.mozilla.org/en/DOM/window.postMessage

The Reverse Proxy method
Method type: Ajax
Setting up a simple reverse proxy on the server, will allow the browser to use relative paths for the Ajax requests, while the server would be acting as a proxy to any remote location.
If using mod_proxy in Apache, the fundamental configuration directive to set up a reverse proxy is the ProxyPass. It is typically used as follows:
ProxyPass /ajax/ http://other-domain.com/ajax/
In this case, the browser would be able to request /ajax/web_service.xml as a relative URL, but the server would serve this by acting as a proxy to http://other-domain.com/ajax/web_service.xml.
One interesting feature of the this method is that the reverse proxy can easily distribute requests towards multiple back-ends, thus acting as a load balancer.

I use JSONP.
Basically, you add
<script src="http://..../someData.js?callback=some_func"/>
on your page.
some_func() should get called so that you are notified that the data is in.

AnyOrigin didn't function well with some https sites, so I just wrote an open source alternative called whateverorigin.org that seems to work well with https.
Code on github.

The most recent way of overcoming the same-origin policy that I've found is http://anyorigin.com/
The site's made so that you just give it any url and it generates javascript/jquery code for you that lets you get the html/data, regardless of it's origin. In other words, it makes any url or webpage a JSONP request.
I've found it pretty useful :)
Here's some example javascript code from anyorigin:
$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
$('#output').html(data.contents);
});

The JSONP comes to mind:
JSONP or "JSON with padding" is a
complement to the base JSON data
format, a usage pattern that allows a
page to request and more meaningfully
use JSON from a server other than the
primary server. JSONP is an
alternative to a more recent method
called Cross-Origin Resource Sharing.

Personally, window.postMessage is the most reliable way that I've found for modern browsers. You do have to do a slight bit more work to make sure you're not leaving yourself open to XSS attacks, but it's a reasonable tradeoff.
There are also several plugins for the popular Javascript toolkits out there that wrap window.postMessage that provide similar functionality to older browsers using the other methods discussed above.

Well, I used curl in PHP to circumvent this. I have a webservice running in port 82.
<?php
$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;
?>
Here is the javascript that makes the call to the PHP file
function getdata(obj1, obj2) {
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
xmlhttp.send();
}
My HTML runs on WAMP in port 80. So there we go, same origin policy has been circumvented :-)

Related

How do I get HTML back from a cURL in PHP vs. an actual link?

I am new to cURL.
When I make the following GET in jquery/ajax, I receive HTML in the response that creates a popup login window (oauth2).
When I use the following code in a backend php script to hit the same endpoint, I get back a clickable link...which, when clicked takes you to a login page.
What am I missing?
The PHP
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://oauthserverxxx.com//login/oauth2/auth?client_id=11111&response_type=code&scope=/auth/userinfo&redirect_uri=http://localhost/oauth_complete.php");
$result = curl_exec($curl);
Response from cURL
You are being redirected.bool(true)
1
The AJAX/jquery
$.ajax({
type: "GET",
url: "https://client.instructure.com//login/oauth2/auth?client_id=6666&response_type=code&redirect_uri=http://oauth_complete.php",
// dataType: 'html',
processData: true,
success: function(canvasAuthHTML) {
$('#flexModalHeader').html('Login...');
$('#flexModalMsg').html(canvasAuthHTML);
$('#flexModal').modal('show');
console.log('Called Canvas - response: ' + canvasTok);
},
error: function (data) {
console.log('Fail - could not get LTI auth token...');
chrome.runtime.sendMessage({ msg: "oauthLTI", token: "failed"});
}
});
Response
This will pop the login form inside the modal - the response from the server is detailed HTML.
could be several things,
first off, the jQuery request probably uses an pre-existing cookie session, your curl request doesn't have any cookies.
second, the jQuery request follows "Location" http-header-redirects, your curl code doesn't, but if that is the problem, you can instruct curl to do the same by setting CURLOPT_FOLLOWLOCATION to 1.
third, the jQuery request has an user-agent string, your curl request does not (libcurl has no default user-agent. the curl cli program does, but libcurl, which you use through php's curl_ functions, doesn't.), some websites block requests with no user-agent. if that's the problem, you can simply copy jQuery's user-agent string and tell curl to use it with CURLOPT_USERAGENT
fourth, by default, most browsers use compression where possible, but your curl request doesn't support compression. it's unlikely, but possible, that the server handles curl's request differently because it doesn't support compressed transfers, if that's the problem, you can enable compression in your curl request by setting CURLOPT_ENCODING to emptystring (that will enable all compressions that libcurl was compiled with, which is usually gzip and deflate) - actually, i recommend doing this regardless, because you're fetching HTML, which compresses really well, so unless your cpu is really slow, it will also make the code execute faster. that's the same reason browsers do it by default.
.- the most reliable way to find the culprit, is to record both requests, compare them side by side, and take away every single difference in the 2 requests, 1 by 1, until the requests are identical. sooner or later, you'll find the difference that made the server respond differently (and my best guess here is a location redirect), for that, i recommend the program FiddlerProxy

set header on jQuery ajax call [duplicate]

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The same origin policy
I wanted to make a community wiki regarding HTML/JS same-origin policies to hopefully help anyone searching for this topic. This is one of the most searched-for topics on SO and there is no consolidated wiki for it so here I go :)
The same origin policy prevents a
document or script loaded from one
origin from getting or setting
properties of a document from another
origin. This policy dates all the way
back to Netscape Navigator 2.0.
What are some of your favorite ways to go around same-origin policies?
Please keep examples verbose and preferably also link your sources.
The document.domain method
Method type: iframe.
Note that this is an iframe method that sets the value of document.domain to a suffix of the current domain. If it does so, the shorter domain is used for subsequent origin checks. For example, assume a script in the document at http://store.company.com/dir/other.html executes the following statement:
document.domain = "company.com";
After that statement executes, the page would pass the origin check with http://company.com/dir/page.html. However, by the same reasoning, company.com could not set document.domain to othercompany.com.
With this method, you would be allowed to exectue javascript from an iframe sourced on a subdomain on a page sourced on the main domain. This method is not suited for cross-domain resources as browsers like Firefox will not allow you to change the document.domain to a completely alien domain.
Source: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
The Cross-Origin Resource Sharing method
Method type: AJAX.
Cross-Origin Resource Sharing (CORS) is a W3C Working Draft that defines how the browser and server must communicate when accessing sources across origins. The basic idea behind CORS is to use custom HTTP headers to allow both the browser and the server to know enough about each other to determine if the request or response should succeed or fail.
For a simple request, one that uses either GET or POST with no custom headers and whose body is text/plain, the request is sent with an extra header called Origin. The Origin header contains the origin (protocol, domain name, and port) of the requesting page so that the server can easily determine whether or not it should serve a response. An example Origin header might look like this:
Origin: http://www.stackoverflow.com
If the server decides that the request should be allowed, it sends a Access-Control-Allow-Origin header echoing back the same origin that was sent or * if it’s a public resource. For example:
Access-Control-Allow-Origin: http://www.stackoverflow.com
If this header is missing, or the origins don’t match, then the browser disallows the request. If all is well, then the browser processes the request. Note that neither the requests nor responses include cookie information.
The Mozilla team suggests in their post about CORS that you should check for the existence of the withCredentials property to determine if the browser supports CORS via XHR. You can then couple with the existence of the XDomainRequest object to cover all browsers:
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
Note that for the CORS method to work, you need to have access to any type of server header mechanic and can't simply access any third-party resource.
Source: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
The window.postMessage method
Method type: iframe.
window.postMessage, when called, causes a MessageEvent to be dispatched at the target window when any pending script that must be executed completes (e.g. remaining event handlers if window.postMessage is called from an event handler, previously-set pending timeouts, etc.). The MessageEvent has the type message, a data property which is set to the string value of the first argument provided to window.postMessage, an origin property corresponding to the origin of the main document in the window calling window.postMessage at the time window.postMessage was called, and a source property which is the window from which window.postMessage is called.
To use window.postMessage, an event listener must be attached:
// Internet Explorer
window.attachEvent('onmessage',receiveMessage);
// Opera/Mozilla/Webkit
window.addEventListener("message", receiveMessage, false);
And a receiveMessage function must be declared:
function receiveMessage(event)
{
// do something with event.data;
}
The off-site iframe must also send events properly via postMessage:
<script>window.parent.postMessage('foo','*')</script>
Any window may access this method on any other window, at any time, regardless of the location of the document in the window, to send it a message. Consequently, any event listener used to receive messages must first check the identity of the sender of the message, using the origin and possibly source properties. This cannot be understated: Failure to check the origin and possibly source properties enables cross-site scripting attacks.
Source: https://developer.mozilla.org/en/DOM/window.postMessage
The Reverse Proxy method
Method type: Ajax
Setting up a simple reverse proxy on the server, will allow the browser to use relative paths for the Ajax requests, while the server would be acting as a proxy to any remote location.
If using mod_proxy in Apache, the fundamental configuration directive to set up a reverse proxy is the ProxyPass. It is typically used as follows:
ProxyPass /ajax/ http://other-domain.com/ajax/
In this case, the browser would be able to request /ajax/web_service.xml as a relative URL, but the server would serve this by acting as a proxy to http://other-domain.com/ajax/web_service.xml.
One interesting feature of the this method is that the reverse proxy can easily distribute requests towards multiple back-ends, thus acting as a load balancer.
I use JSONP.
Basically, you add
<script src="http://..../someData.js?callback=some_func"/>
on your page.
some_func() should get called so that you are notified that the data is in.
AnyOrigin didn't function well with some https sites, so I just wrote an open source alternative called whateverorigin.org that seems to work well with https.
Code on github.
The most recent way of overcoming the same-origin policy that I've found is http://anyorigin.com/
The site's made so that you just give it any url and it generates javascript/jquery code for you that lets you get the html/data, regardless of it's origin. In other words, it makes any url or webpage a JSONP request.
I've found it pretty useful :)
Here's some example javascript code from anyorigin:
$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
$('#output').html(data.contents);
});
The JSONP comes to mind:
JSONP or "JSON with padding" is a
complement to the base JSON data
format, a usage pattern that allows a
page to request and more meaningfully
use JSON from a server other than the
primary server. JSONP is an
alternative to a more recent method
called Cross-Origin Resource Sharing.
Personally, window.postMessage is the most reliable way that I've found for modern browsers. You do have to do a slight bit more work to make sure you're not leaving yourself open to XSS attacks, but it's a reasonable tradeoff.
There are also several plugins for the popular Javascript toolkits out there that wrap window.postMessage that provide similar functionality to older browsers using the other methods discussed above.
Well, I used curl in PHP to circumvent this. I have a webservice running in port 82.
<?php
$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;
?>
Here is the javascript that makes the call to the PHP file
function getdata(obj1, obj2) {
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
xmlhttp.send();
}
My HTML runs on WAMP in port 80. So there we go, same origin policy has been circumvented :-)

PHP REST put/delete options

Trying to understand the REST method of creating apps in PHP.
I'm having a problem in understanding how to send put/delete from php script.
In the internet I can only find how to determine which php method has been sent.
if($_SERVER['REQUEST_METHOD'] == 'DELETE')
But how to send this DELETE method?
Normaly what I do when want to delete some record from DB i have normal html form with method set to post/get and record db id then I press submit button to send post/get form.
How to create this submit to send delete/put methods?
There are two common ways to send a request from an HTML page, using an http method other than GET or POST.
#1: use an html form to send a POST request, but include a hidden form field that tells the server to treat the request as though it were using a different method. This is the approach outlined by #xdazz.
<form method="post" action="my_resource.php">
...
<input type="hidden" name="REQUEST_METHOD" value="PUT" />
<form>
In your PHP script, "my_resource.php", you'll have to look at both the real request method, and the submitted form field, to determine which logic to invoke:
/* my_resource.php */
$method = strtolower($_SERVER['REQUEST_METHOD']);
if( $method === 'post' && isset($_REQUEST['REQUEST_METHOD'])) {
$tmp = strtolower((string)$_REQUEST['REQUEST_METHOD']);
if( in_array( $tmp, array( 'put', 'delete', 'head', 'options' ))) {
$method = $tmp;
}
unset($tmp);
}
// now, just run the logic that's appropriate for the requested method
switch( $method ) {
case "get":
// logic for GET here
break;
case "put":
// logic for PUT here
break;
case "post":
// logic for POST here
break;
case "delete":
// logic for DELETE here
break;
case "head":
// logic for DELETE here
break;
case "options":
// logic for DELETE here
break;
default:
header('HTTP/1.0 501 Not Implemented');
die();
}
Note: you can put the above logic into each page (or call it from each page). An alternative is to build a proxy script, (eg. "rest-form-proxy.php"). Then, all forms in your site will submit to the proxy, including a request_method, and a target url. The proxy will extract the provided information, and forward the request on to the desired url using the proper requested http method.
The proxy approach is a great alternative to embedding the logic in each script. If you do build the proxy though, be sure to check the requested URL, and dis-allow any url that doesn't point back to your own site. Failure to do this check will allow others to use your proxy to launch malicious attacks on other websites; and it could also compromise security and/or privacy on your website.
--
#2: Use Javascript, in your HTML page, to initiate an XMLHttpRequest. This is a more complex approach, which requires a bit of javascript, but it can be more flexible in some cases. It allows you to send requests to the server without re-loading the page. It also allows you to send data in many different formats (you are not limited to sending only data from an html form). For example:
<button onclick="doSave()">Save</button>
<script>
var myObject = {
// ... some object properties that
// that you'll eventually want to save ...
};
function doSave() {
var xhr = createxmlhttprequest();
// initialize the request by specifying the method
// (ie: "get", "put", "post", "delete", etc.), and the
// url (in this case, "my_resource.php"). The last param
// should always be `true`.
xhr.open("put", "my_resource.php", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function() {
if (xhr.readystate != 4) { return; }
var serverresponse = xhr.responsetext;
// ... this code runs when the response comes back
// from the server. you'll have to check for success
// and handle the response document (if any).
};
// this initiates the request, sending the contents
// of `myObject` as a JSON string.
xhr.send(JSON.stringify(myObject));
// The request runs in the background
// The `onreadystatechange` function above
// detects and handles the completed response.
}
</script>
There's a lot more to XMLHttpRequest than I've shown in the basic example above. If you choose this route, please research it thoroughly. Among other things, make sure you handle the various error conditions properly. There are also a number of issues with cross-browser compatibility, many of which can be addressed by using an intermediary, like jQuery's $.ajax() function.
Finally, I should note that the two methods above are not mutually exclusive. It's quite possible to use forms for some requests, and XMLHttpRequest for others, as long as you build your server so that it can handle either kind of request (as shown in #1 above).
HTML forms only support GET and POST, so in a normal web application, you need to use a hidden field to specify the request method, which is most frameworks do.
<form method="post" action="...">
...
<input type="hidden" name="REQUEST_METHOD" value="PUT" />
<form>
The usual way to do this is to use cURL
$ch = curl_init('YOUR_URL');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); // curl_setopt($ch, CURLOPT_PUT, true); - for PUT
curl_setopt($ch, CURLOPT_POSTFIELDS, 'some_data');
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0); // DO NOT RETURN HTTP HEADERS
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // RETURN THE CONTENTS OF THE CALL
$result = curl_exec($ch);
If you are on Chrome, you can use Postman to test your REST service. It allows sending any type of command - DELETE, PUT, but also OPTIONS, PATCH, etc.
On Firefox, you can use RESTClient among others.

cross origin policy, using remote page but access localhost data in the same computer [duplicate]

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
The same origin policy
I wanted to make a community wiki regarding HTML/JS same-origin policies to hopefully help anyone searching for this topic. This is one of the most searched-for topics on SO and there is no consolidated wiki for it so here I go :)
The same origin policy prevents a
document or script loaded from one
origin from getting or setting
properties of a document from another
origin. This policy dates all the way
back to Netscape Navigator 2.0.
What are some of your favorite ways to go around same-origin policies?
Please keep examples verbose and preferably also link your sources.
The document.domain method
Method type: iframe.
Note that this is an iframe method that sets the value of document.domain to a suffix of the current domain. If it does so, the shorter domain is used for subsequent origin checks. For example, assume a script in the document at http://store.company.com/dir/other.html executes the following statement:
document.domain = "company.com";
After that statement executes, the page would pass the origin check with http://company.com/dir/page.html. However, by the same reasoning, company.com could not set document.domain to othercompany.com.
With this method, you would be allowed to exectue javascript from an iframe sourced on a subdomain on a page sourced on the main domain. This method is not suited for cross-domain resources as browsers like Firefox will not allow you to change the document.domain to a completely alien domain.
Source: https://developer.mozilla.org/en/Same_origin_policy_for_JavaScript
The Cross-Origin Resource Sharing method
Method type: AJAX.
Cross-Origin Resource Sharing (CORS) is a W3C Working Draft that defines how the browser and server must communicate when accessing sources across origins. The basic idea behind CORS is to use custom HTTP headers to allow both the browser and the server to know enough about each other to determine if the request or response should succeed or fail.
For a simple request, one that uses either GET or POST with no custom headers and whose body is text/plain, the request is sent with an extra header called Origin. The Origin header contains the origin (protocol, domain name, and port) of the requesting page so that the server can easily determine whether or not it should serve a response. An example Origin header might look like this:
Origin: http://www.stackoverflow.com
If the server decides that the request should be allowed, it sends a Access-Control-Allow-Origin header echoing back the same origin that was sent or * if it’s a public resource. For example:
Access-Control-Allow-Origin: http://www.stackoverflow.com
If this header is missing, or the origins don’t match, then the browser disallows the request. If all is well, then the browser processes the request. Note that neither the requests nor responses include cookie information.
The Mozilla team suggests in their post about CORS that you should check for the existence of the withCredentials property to determine if the browser supports CORS via XHR. You can then couple with the existence of the XDomainRequest object to cover all browsers:
function createCORSRequest(method, url){
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr){
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined"){
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
var request = createCORSRequest("get", "http://www.stackoverflow.com/");
if (request){
request.onload = function() {
// ...
};
request.onreadystatechange = handler;
request.send();
}
Note that for the CORS method to work, you need to have access to any type of server header mechanic and can't simply access any third-party resource.
Source: http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
The window.postMessage method
Method type: iframe.
window.postMessage, when called, causes a MessageEvent to be dispatched at the target window when any pending script that must be executed completes (e.g. remaining event handlers if window.postMessage is called from an event handler, previously-set pending timeouts, etc.). The MessageEvent has the type message, a data property which is set to the string value of the first argument provided to window.postMessage, an origin property corresponding to the origin of the main document in the window calling window.postMessage at the time window.postMessage was called, and a source property which is the window from which window.postMessage is called.
To use window.postMessage, an event listener must be attached:
// Internet Explorer
window.attachEvent('onmessage',receiveMessage);
// Opera/Mozilla/Webkit
window.addEventListener("message", receiveMessage, false);
And a receiveMessage function must be declared:
function receiveMessage(event)
{
// do something with event.data;
}
The off-site iframe must also send events properly via postMessage:
<script>window.parent.postMessage('foo','*')</script>
Any window may access this method on any other window, at any time, regardless of the location of the document in the window, to send it a message. Consequently, any event listener used to receive messages must first check the identity of the sender of the message, using the origin and possibly source properties. This cannot be understated: Failure to check the origin and possibly source properties enables cross-site scripting attacks.
Source: https://developer.mozilla.org/en/DOM/window.postMessage
The Reverse Proxy method
Method type: Ajax
Setting up a simple reverse proxy on the server, will allow the browser to use relative paths for the Ajax requests, while the server would be acting as a proxy to any remote location.
If using mod_proxy in Apache, the fundamental configuration directive to set up a reverse proxy is the ProxyPass. It is typically used as follows:
ProxyPass /ajax/ http://other-domain.com/ajax/
In this case, the browser would be able to request /ajax/web_service.xml as a relative URL, but the server would serve this by acting as a proxy to http://other-domain.com/ajax/web_service.xml.
One interesting feature of the this method is that the reverse proxy can easily distribute requests towards multiple back-ends, thus acting as a load balancer.
I use JSONP.
Basically, you add
<script src="http://..../someData.js?callback=some_func"/>
on your page.
some_func() should get called so that you are notified that the data is in.
AnyOrigin didn't function well with some https sites, so I just wrote an open source alternative called whateverorigin.org that seems to work well with https.
Code on github.
The most recent way of overcoming the same-origin policy that I've found is http://anyorigin.com/
The site's made so that you just give it any url and it generates javascript/jquery code for you that lets you get the html/data, regardless of it's origin. In other words, it makes any url or webpage a JSONP request.
I've found it pretty useful :)
Here's some example javascript code from anyorigin:
$.getJSON('http://anyorigin.com/get?url=google.com&callback=?', function(data){
$('#output').html(data.contents);
});
The JSONP comes to mind:
JSONP or "JSON with padding" is a
complement to the base JSON data
format, a usage pattern that allows a
page to request and more meaningfully
use JSON from a server other than the
primary server. JSONP is an
alternative to a more recent method
called Cross-Origin Resource Sharing.
Personally, window.postMessage is the most reliable way that I've found for modern browsers. You do have to do a slight bit more work to make sure you're not leaving yourself open to XSS attacks, but it's a reasonable tradeoff.
There are also several plugins for the popular Javascript toolkits out there that wrap window.postMessage that provide similar functionality to older browsers using the other methods discussed above.
Well, I used curl in PHP to circumvent this. I have a webservice running in port 82.
<?php
$curl = curl_init();
$timeout = 30;
$ret = "";
$url="http://localhost:82/put_val?val=".$_GET["val"];
curl_setopt ($curl, CURLOPT_URL, $url);
curl_setopt ($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt ($curl, CURLOPT_MAXREDIRS, 20);
curl_setopt ($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.5) Gecko/2008120122 Firefox/3.0.5");
curl_setopt ($curl, CURLOPT_CONNECTTIMEOUT, $timeout);
$text = curl_exec($curl);
echo $text;
?>
Here is the javascript that makes the call to the PHP file
function getdata(obj1, obj2) {
var xmlhttp;
if (window.XMLHttpRequest)
xmlhttp=new XMLHttpRequest();
else
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","phpURLFile.php?eqp="+obj1+"&val="+obj2,true);
xmlhttp.send();
}
My HTML runs on WAMP in port 80. So there we go, same origin policy has been circumvented :-)

Ajax GET request turning into OPTION request

I'm experiencing a weird behavior with an ajax request on a godaddy shared linux server.
The request works perfectly on many other servers I've tested it on, but on this one, the GET request turns into an OPTIONS request for some reason.
Here's the js code (using mootools 1.1):
var a = new Ajax(myurl,{
method: 'get',
onComplete: function( response ){
$('my_div').style.display="none";
output_display( response );
}
});
a.request();
You can see that the method is defined as GET. Yet when I watch the request happen with Firebug, it gets passed as an OPTIONS request. Any thoughts on how or why this would happen?
usually, there are two reasons for this sort of behaviour during XHR (ajax) requests.
protocol bridging (from https to http or vice versa) whereby request url protocol differs to requested url
subdomain difference (eg, domain.com requests from www.domain.com)
bottom line: for XHR to work, protocol and hostnames need to match due to access control restrictions.
reads:
http://www.w3.org/TR/access-control/#cross-origin-request-with-preflight0
ways around cross-domain policy restrictions:
http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
etc etc.

Categories