Cross domain xmlhttp - php

I am writing this javascript that will be used on several other domains which calls a php script(only on my domain) to return an array. I am using xmlhttp and it works great when testing on my domain, but as soon as the javascript is placed or called from a separate domain it completely breaks. Anybody know how to make this request cross-domain?
Note: I had to perform a weird little hack to allow me to make two separate calls and make sure that they were both returned before processing. Anyways this does work perfectly every time on my domain.
This is tin the javascript file that calls my php code for the array
function getUrls(){
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
xmlhttp2 = new XMLHttpRequest();
}
else {
// code for IE5 and IE6
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
// code for IE5 and IE6
xmlhttp2 = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200 ) {
parsedJSONurls = JSON.parse(xmlhttp.responseText);
xmlhttp2.open("GET", "http://mydomain.com/connect.php?q=companies", true);
xmlhttp2.send();
}
}
xmlhttp2.onreadystatechange = function(){
if (xmlhttp2.readyState == 4 && xmlhttp2.status == 200) {
parsedJSONcompanies = JSON.parse(xmlhttp2.responseText);
runLoop(parsedJSONurls, parsedJSONcompanies);
}
}
xmlhttp.open("GET", "http://mydomain.com/connect.php?q=urls", true);
xmlhttp.send();
}

Try adding this header to your connect.php file
header('Access-Control-Allow-Origin: http://domain1.com, http://domain2.com');
If you want to permit all domains instead of a whitelist
header('Access-Control-Allow-Origin: *');
https://developer.mozilla.org/en/http_access_control

The reason for this is the same origin policy. It was put in place to stop malicious scripts from accessing sensitive data from other websites. You should look into writing a JSONP request as a workaround for your problem.

There's an ongoing community wiki I started last year that explains many ways of circumventing the same origin policy. A solution that fits your situation can most likely be found there.

Same with others, it's caused by same origin policy.
Suppose page is at "a.com", no matter where JavaScript file is,
As long as you use XMLHttpRequest approach, you can only access data from a.com.
Even subdomain a.a.com can't access a.com.
You can have 2 options:
1) Use <script/> tag hack
JSONP is great, but it seems you don't rely on any library.
It's a JavaScript nature you can include JavaScript locating on other domain. <script/> tag hack is a simple technique which dynamically create and append <script/> node.
And its src attribute is the URL which is in different domain.
function getUrl(url) {
var scriptEl = document.createElement("script");
scriptEl.src = url;
scriptEl.async = true;
document.getElementsByTagName("head")[0].appendChild(scriptEl);
}
// Predefined callbacks
window.companyCallback = function (responseData) {
parsedJSONCompanies = responseData;
};
window.urlCallback = function (responseData) {
parseJSONurls = responseData;
};
getUrl("http://mydomain.com/connect.php?q=companies");
getUrl("http://mydomain.com/connect.php?q=urls");
Of course you also have to modify your PHP to meet the need.
<?php
header("content-type: application/json");
if ($_GET['q'] === "urls")
{
echo "companyCallback(";
json_encode($result);
echo ");";
}
else
{
echo "urlCallback(";
json_encode($result);
echo ");";
}
?>
2) Place proxy.php in different domain
The above method is what I recommended.
If you don't want to revamp your code heavily, use proxy technique instead.
You must have privilege to add a proxy.php on different hosts.
The content like this:
<?php
$url = "http://mydomain.com/connect.php?q=" . $_GET["q"];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo $result;
?>
NOTE: Be careful about security issue, you need to check where the request from.
In JavaScript, you just need to point the url in xmlhttp.open() to this same domain PHP.
xmlhttp.open("proxy.php?q=urls", true);
Hope it helps.

Like others said you could use JSON-p) for that or if the browsers supports(new A-graded browsers do) CORS you could use that instead.

As mentioned most non html5 dont allow cross browser ajax requests. To get around this I call a remote javascript script.
use javascript to add a line like
<script type="text/javascript" src="http://www.somemedomain.xxx/myjavascript.php?arg1=xxx&arg">
on the myjavascript.php file on the other server, you can process, collect information collected from the browser.
you have to encode the php file as javascript.
header( "content-type: application/javascript" ) //check php.net
This will work in ie6+

Related

Using AJAX for GET data from other server on Mouse Over

I am searching for this from yesterday, Do not know, I am unable to implement, or going in wrong direction.
My currently ajax function which is working with local server
function tooltipajax(r_ID)
{
var str ;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById('span'+ r_ID).innerHTML = xmlhttp.responseText ;
}
}
xmlhttp.open("GET","accounteditajax.php?key=" +r_ID,true);
xmlhttp.send();
}
PHP code:
print("<tr bgcolor=\"#EEEEEF\">");
print("<td class='normal' id=\"serialno\" onMouseOver='tooltipajax(this.id)'>
<a class=\"tooltip\" >Serial Number <span id=\"spanserialno\"
class=\"custom info\"></span> </a></td>");
print("<td bgcolor = \"#FFFFFF\" ><b>$serial</b></td>\n");
print("</tr>\n");
How can I get data from another server?
xmlhttp.open("GET","accounteditajax.php?key=" +r_ID,true);
I want to get from
http://iphere/filename.php
If you use use jQuery like so, this works.
function tooltip_ajax(r_ID) {
$.ajax({
url: "http://iphere/filename.php?id=" + r_ID,
context: document.body,
success: function(data) {
if(data) {
$('span' + r_ID).html(data);
}
}
});
}
That's tested with a different server and it works.
In order to retrieve data from another server using AJAX, you will need to utilize JSONP. This is due to Cross-Domain restrictions on AJAX requests. To expand on this further, if you wanted to make an AJAX request from a page located at http://test1.com, to a page / script located at http://test2.com, you would not be allowed.
Check out this article for more information: http://www.jquery4u.com/json/jsonp-examples/
Basically, JSONP involves adding a temporary SCRIPT tag to the page, which CAN load external content. The URL for this SCRIPT tag contains data, and a callback function name. The JSONP should then respond with the data, enclosed in a call to that function. Of course, the one downside is that the target server must support JSONP requests.
One alternative is using a bridge PHP script locally, that utilizes CURL to make the request, and return the information to your page, via AJAX.
For a bit more information regarding utilizing CURL in PHP, take a look at this article: http://codular.com/curl-with-php

Form POST to 2 URLS

I need to post a single form to 2 different URLs. One is just a logging script so the response doesn't need to be passed back to the user.
Unfortunately in this instance I can't just post to a single PHP script and turn around and re-POST it using Curl. This has to be done in the user's browser.
This is some Javascript I'm using right now but it's failing at a seemingly random rate for almost all the major browsers (but works 95%+ of the time). The rest of the form does require Javascript to function so I know the problem isn't just that some users have Javascript turned off.
function makePOSTRequest(url, parameters) {
http_request = false;
if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/html');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
http_request.open('POST', url, true);
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", parameters.length);
http_request.setRequestHeader("Connection", "close");
http_request.send(parameters);
}
I'm calling that after building the request manually in another function, then calling the submit() function of the form.
Can anyone suggest an alternative that might work better? This seems to be working ~95% of the time but that 5% failure rate is a killer... Thanks!
Try using a framework that supports error checking any try repeating the request on failure.
JavaScript frameworks like jQuery support sending post requests and can be used to check if a request was successful. Also your code will be easier to write and maintain.

How to make documents upload using AJAX with progress Bar

I want to make an upload page for my site so that documents get uploaded asynchronously, I tried using AJAX, but AJAX has a limited access to the users filesystem, and when the information is sent to the server only the file name appears without the directory, I would like suggestion on how to do this easily without using JQuery, and also I would like to know if there is a way to monitor the progress of a file upload, so that I could add a progress bar to my site.
function createXMLHttpRequestObject(){
var xmlHttp = 3;
if(window.ActiveXObject){
try{
//test for new version of internet Explorer
xmlHttp = new ActiveXObject("Msxml.XMLHTTP");
}
catch(e){
try{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e){
xmlHttp = 2;
}
}
}
else{
try{
xmlHttp = new XMLHttpRequest();
}
catch(e){
xmlHttp = 1;
}
}
if(!xmlHttp){
alert("Error creating Objece");
}
else{
var xHttpArr = new Array();
xHttpArr.push(xmlHttp);
var i = xHttpArr.length - 1;
return xHttpArr[i];
}
}
function process(xmlHttp, i){
if(xmlHttp.readyState == 4 || xmlHttp.readyState == 0){
//value = encodeURIComponent( objRef.value );
xmlHttp.open("GET", "php/AjaxBody.php?value="+i, true);
xmlHttp.onreadystatechange = handleServerResponse;
xmlHttp.send(null);
}
else{
alert("Hold on");
}
}
function handleServerResponse(){
if(test.readyState == 1 || test.readyState == 2 || test.readyState == 3){
}
if (test.readyState == 4){
if(test.status == 200){
txtResponse = test.responseText;
bodyDiv = document.getElementById("body");
bodyDiv.innerHTML = txtResponse;
}
else{
alert("Error with the xmlHttp status");
}
}
/*
else{
alert("Error with the xmlHttp readystate: " + x.status);
} */
}
Above is the code that creates the Object
button.onclick = function() {
send = createXMLHttpRequestObject();
frmUpload = document.getElementById("frmUpload");
file = document.getElementById("fileUpload");
processSending(send, frmUpload);
}
Above when the process method is called to send the file,
on the server I try to echo the file path, only the the name appears, like this
<?php
echo $_GET['value'];
?>
First of all you are doing your file upload wrong. File uploads require you to do a proper POST request using forms as it requires the enctype form attribute to be multipart/form-data. Why? The browser sends the binary file data through the POST request and does the hard work of encoding the data correctly through the POST request to be read on the server. Any other way and you will just be getting the file name at the server (you can verify this with a tool like Fiddler).
Alright, then how do you do a file upload using AJAX? AFAIK it's not possible to read the user's file system directly (I think FileReader only allows reading through the sandboxed file system through the browser but I may be wrong here), so IMO there are 2 ways to go here:
Using a hidden iframe approach for the file upload. Google it you will find lots of info it.
Use a Flash based uploader. More on this at the end.
As far as getting the location of the file on the users file system using Javascript goes, forget about it. It's considered a security concern and many browsers only return the file name on reading the element value when using the HTML input file tag. (Unless you are thinking of using a flash component. More on that in the last point.)
Now coming to the progress bar issue. When your PHP script is actually run the entire file has already been uploaded to the server. So how to show a progress bar? A few (hackish) ways:
An old school approach is to create a CGI script on the server to handle the upload. The advantage? CGI scripts can be run during the upload allowing you to retrieve the actual byte level progress of the upload. But this also requires you to update the progress at some place on the server which you can poll (with a separate AJAX request) and show in the browser to the user.
Another most commonly used approach is using a flash based uploader (please don't kill me StackOverflow community). Yes it's still used by big names (I am looking at you Facebook). The advantage you will have is that you don't need any special scripts on the server. The Flash based client is fully aware of the number of bytes uploaded. Also you may have access to the actual file path string (note the use of may and string) which is not so openly possible with plain JS and HTML.
You could use a FileReader and read the file into an ArrayBuffer or a BinaryString and then use multiple requests to send for example 1 mb sized packages. The receiving php script would then have to 'rebuild' the file by appending each received part to it. This would also solve the problem of echoing the file path on the server as you can (and have to) decide where to save it before writing to it.

Fetching file with AJAX, can't read PHP

I have checked the suggestions that came up before posting, hope I didn't miss anything now.
I have a piece of code that I use to get txt-files for my website but now I need to redo the code so it gets both txt and php-files, but it just won't read the php-script. I'm a bit afraid to mess up the code at this moment so I'm walking on the safe side of the road and ask here if anyone knows a good add to the code. It's quite embarrasing that I still have codes for IE 5&6 in it, so if you wish to remove that at the same time, go ahead. I won't hate you for it, I promise.
UPDATE:
I have four files:
html - Calling the .js-file with the ajax-script.
js - With all my javascript(and simular)-codes.
php - That contains... Well, you get the point.
I have to call the php-code somehow, like I call my txt-files, but of course so the php works as it should. I am very new to AJAX, so I don't dare to mess around with this code at the moment, but I figured that I might be able to add some kind of if-statement that calles the php-file as it is intended to be.
But I have no clue what that code might be and where to put it for things to work accordingly. Any help would be appritiated and credited in the code, of course.
Heres the AJAX-code that is contained within the .js-file:
/*Load the link.*/
function loadXMLDoc(url)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("leftCol").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET",url,true);
xmlhttp.send();
}
/*Highly unnecessary, but I wanted to see if it worked and it looks better on the .html-page.*/
function get_link(url)
{
loadXMLDoc(url);
}
As the above commenter said, it is best to use a 3rd party tool for such things - if for no other reason than to greatly increase cross-browser compatibility.
if you were to use jQuery, the code would be reduced to.
function get_link(url)
{
$.ajax({url: url, success: success:function(result){
//the code / resulting string will be in the result variable.
}});
}
jQuery CDN Hosted: http://code.jquery.com/jquery-1.5.min.js
Let me ask this... if you change your code to
function get_link(url)
{
window.location=url;
}
Does your web browser successfully navigate to the page you are trying to retrieve via AJAX? If not, there is likely a problem with your PHP syntax.
it just won't read the php-script
It's a rather vague statement, but here are few pointers that could be the solution :
PHP file are interpreted on the server so when you do an Ajax call to that page what you receive on the client side is the result of that php script, not his content.
You are assigning the result of the query directly in the HTML, if the result contains data that does not render anything, you won't see anything. For example the content <script>Text here bla bla bla</script> will just show nothing.
If you want to make sure you get some data back from a file, you can just alert the content when you receive it.
Make sure your path to your PHP page is correct. To detect if the file is not giving a 404 error code or any other error code, you can use this :
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
document.getElementById("leftCol").innerHTML = xmlhttp.responseText;
} else {
alert("Error " + xmlhttp.status);
}
}
}

XMLhttpRequest > PHP > XMLhttpRequest

I have another question. XMLhttpRequests haunt me. Everything is now in the database but I need this data to update my page on firt page load or reload. The XHR is triggered in JavaScript file which triggers PHP-Script. PHP-Script access MySQL database. But how do I get the fetched records back into my JavaScript for page update. I can not figure it out.
First my synchronous XMLhttpRequest:
function retrieveRowsDB()
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET","retrieveRowData.php", false);
xmlhttp.send(null);
return xmlhttp.responseText;
}
Then my PHP-Script:
<?php
$con = mysql_connect("localhost","root","*************");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("sadb", $con);
$data="SELECT * FROM users ORDER BY rowdata ASC";
if (!mysql_query($data,$con))
{
die('Error: ' . mysql_error());
}
else
{
$dbrecords = mysql_query($data,$con);
}
$rowdata = mysql_fetch_array($dbrecords);
return $rowdata;
mysql_close($con);
?>
What am I missing here? Anyone got a clue?
PHP scripts don't return to JavaScript. You have to echo the data (encoded in some way, for example json_encode).
Really, if you're doing any kind of ajax, you'll make your life a lot easier by using an ajax library.
There's not much technically wrong with your code so far - you just need to actually do something with it.
In your PHP file, instead of return $rowdata;, you need to output it in some way. Currently, it's just sending a blank document back to the javascript, so you'll need to echo out the code. Normally, when using a number of objects to be returned to javascript, JSON is a good format. Check out json_encode.
On the other side, in the js, you'll need to take the response and update the page in some manner. Currently, you're just returning it again.
I suggest you go through a few ajax tutorials, and consider using a framework such as jQuery to do the heavy lifting for you. You might also want to do a bit of reading on this topic, as you have some fundamental misconceptions.
The problem is xmlhttp.responseText, it doesn't exist at the time, try adding this just before your return statement:
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
doSomething(xmlhttp.responseText);
}
}
}
Basically you have to wait until the data is available, it takes time to make an HTTP request and get a response.

Categories