I am having problems with this topic: Access-Control-Allow-Origin.
I read about it and I found that is possible to get response using php, here
But I don't know how to adapt that code to javascript, I still have the same problem.
I tried this in javascript:
var url ='http://localhost:8080/com.webserver/rest/manage/order?parameter=parameter';
req=Ajax("getResponse.php/?" + url)
if (req.status=200)
alert("hi");
And on php file:
<?php
echo file_get_contents($_GET['url']);
?>
And nothing happends. I tried with ajax, something like:
$.ajax({
url: "http://localhost:8080/com.webserver/rest/manage/order?parameter=parameter",
async: false,
dataType: 'html',
success: function (text) {
alert(text);
}
});
But always same problem....
I read lot of people on internet having the same problem, but no one get a response. I just found 2 ways, using chrome and one option but just recomended for developers and adding headers on server but I don't know where to add them. I am using apache tomcat catalina for that localhost. I have 2 servers, webpage (in xampp) and rest (in tomcat)
Change
req=Ajax("getResponse.php/?" + url)
to
req=Ajax("getResponse.php/?url=" + url)
Bare in mind this is insecure, i could pass anything into the url parameter and your php scripts would use it. Allowing people to read files from your local system as well as get your php script to download malicious files from elsewhere
Edit:
To best way to secure it is to use an actions list, this means that the user never see's the url and can only modify an action word. for example
req=Ajax("getResponse.php/?do=getOrders")
then in php
$actions = array();
$actions['getOrders'] = "http://localhost:8080/com.webserver/rest/manage/order?parameter=parameter";
if(array_key_exists($_GET['do'], $actions))
echo file_get_contents($actions[$_GET['do']]);
Usually you'd want to do more that just translate an action to a url, you may want to pass additional parameters. In this case you could use a switch or a bunch of IF's to check if $_GET['do'] is equal to something and then process it. but it would take hours to give an example of every possible implementation method, so you may want to use google.
Please note: whilst this method is suggest adds 100x more security to your script, its not infallable, especially if you start passing through parameters from users too. Once again use google.
Related
In the existing SO literature, I have seen examples that use jquery and PHP to proxy data:
jquery
function loadTheUrl(x){
$.ajax({ url: 'loader.php',
data: {url: x},
type: 'get',
success: function(output) {
$('.loading-space').html(output);
}
});
}
PHP
<?php
$doc = new DOMDocument();
$doc->loadHTML(file_get_contents($_GET['https://www.google.com/finance/getprices?q=.NSEI&x=NSE&i=600&p=1d&f=d,o']));
echo $doc->saveHTML();
Here is what the first few lines of the data look like at the URL seen in the PHP above. It is a page of plain text only, like this:
MARKET_OPEN_MINUTE=570
MARKET_CLOSE_MINUTE=960
INTERVAL=300
COLUMNS=DATE,OPEN
DATA=
TIMEZONE_OFFSET=-240
a1521120900,555.45
1,554.53
2,554.07
3,553.9
4,552.67
...
As far as I know, the PHP is correct. For my use case, I need to replicate the above jquery by means of d3. I was hoping that d3 would have something to use to interface with the data my php file is spitting out.
If you are wondering why I am going to such lengths, it's because my browsers are not letting me run scripts (i.e. d3.text(), d3.csv() et all) directly by say d3.text('https://www.google.com/finance...') due to the infamous access control origin header error. So my plan is to mirror the data from the google backfill off a local php file that I'm serving from my server. This way everybody is happy (or at least me).
When I try calling d3.text() on my php file, my data was not loaded correctly. In other words I tried: d3.text('my_loader.php'). But that resulted in lots of NaN errors, which I usually noticed are symptoms of a parsing error of some sort. Checking back through my code, things seem fine though. I have unary parsing in place, the strings should be cast to numbers. In fact, everything was working fine offline. I could load and parse the data directly when in my IDE. It was only when I published my d3 graph to the web did I realize I couldn't parse data from different origins. This is the point where I added the PHP component. My hunch was that d3 was actually trying to parse my PHP page and not the URL the PHP was pointing to. I later confirmed this by passing the data returned by d3.text() in the console and it was indeed the PHP page itself.
Question: In light of my cross-origin data situation, what can I do from the d3 side or the PHP side to make the two interface with each other correctly? I wonder if d3 is only suited for same origin data, or if there actually is a method to read/parse cross-origin data using a technique I'm not aware of (PHP or otherwise).
The url you are fetching does not exist within the $_GET variable.
The parameters you are submitting are an array:
$_GET = ['url' => 'some_url'];
Which means this:
$_GET['https://www.google.com/finance/getprices?q=.NSEI&x=NSE&i=600&p=1d&f=d,o]
is wrong (it's also missing a quote mark at the end of the string).
It should be $_GET['url']
With no validation:
<?php
header('Content-Type: text/plain');
echo file_get_contents($_GET['url']);
But that's neither here nor there.
The issue, I think, is with the url being passed. It contains a question mark and multiple ampersands (? and &). I think this is bjorking up the $_GET parameter so all you're getting is https://www.google.com/finance/getprices?q=.NSEI. You need to wrap the url in encodeURIComponent:
var url = encodeURIComponent('https://www.google.com/finance/getprices?q=.NSEI&x=NSE&i=600&p=1d&f=d,o');
d3.text('/path/to/myscript.php?url=' + url);
Cross origin applies to all ajax requests, instead of requesting d3.text('https://www.google.com/finance...') why not try d3.text('mymethod.php') and make sure the method returns a text file rather than html via the headers:
<?php
header('Content-Type: text/plain');
$file = file_get_contents('https://www.google.com/finance/getprices?q=.NSEI&x=NSE&i=600&p=1d&f=d,o');
echo $file;
I'm new to coding and was pretty proud when I created the following PHP code. Using TwitchTV's API, I can show the game someone is playing on TwitchTV. It works.
$info = "https://api.twitch.tv/kraken/channels/celgaming";
$json = json_decode(file_get_contents($info), true);
$thegame = $json['game'];
echo $thegame;
But I'm planning on caching the page this code is on and realized it won't work because PHP is server side. How do I convert this piece of code to Ajax or some other asynchronous method that will work with page caching?
I´m not sure about an async call being what you need, but I would try that first.
Here is, not a real answer, but hopefully some pointers to it:
Tried to make an Ajax call to "https://api.twitch.tv/kraken/channels/celgaming"
and stumbled upon 'same-domain policy' issue. See below link.
[Solutions to Ajax cross-domain problem][1]
I tried this from [1]: Ways to circumvent the same-origin policy
$.getJSON("https://api.twitch.tv/kraken/search/games?q=star&type=suggest&callback=?", function (data) {
$.each(data.games, function (index, item) {
console.log(index, item);
});
});
It works. Maybe you should scan the API docs for an alternate way to get the data you need.
I won't write you the javascript, you should try that first yourself, but propose other solutions that might solve your primary objective (caching):
you may use a database (e.g. MySQL) instead of client side caching. Just store the result of your TwitchTV query together with an expiration date in your database and check it before sending another request to TwitchTV.
you could send HTTP Cache-Control headers via PHP or included in your HTML code. See this question for instructions: Cache control and expires header for PHP. They suggest to the client to no query the server before the expiration date is reached.
I'm having a helluva time getting ajax calls and responses to work correctly in IE8 (yes, unfortunately, that's the version my workgroup is stuck on), Firefox, and Chrome.
I have the ajax requests going to a single PHP script on the backend. Because I've experienced strange issues in the past where IE will suddenly complain / behave as if some of our internal/intranet servers are actually "cross-domain", I am making sure the PHP script wraps the data object into a callback function:
echo $callback_name.'('.$jsondata.');';
(However, all the ajax requests from the front-end are passing the same callback name, just to try to keep things simple: jsonpCallback.)
My front-end requests all follow this same format:
$.ajax({
type: 'GET',
url: 'ajax_fetcher.php',
data: { action: 'fetchexecmsg', incident_id: incident_id_number},
dataType: 'jsonp', // doing this because it should avoid cross-domain issues
jsonp:'callback_name',
jsonpCallback: 'jsonpCallback',
success: function(data){
console.log("Ajax call to fetchexecmsg was successful.");
Parse_JSON_object_into_Exec_Msg_Div(data);
}
});
I was doing most building / testing with Chrome. So, today, I decided to test Firefox and IE8.
To my surprise, Firefox was complaining that 'jsonpCallback' wasn't an actual function ??
TypeError: jsonpCallback is not a function (red text in the console)
My understanding was that if I had a "success" function already pre-defined, there'd be no need for that function to actually exist ?
So, I put that in globally as an empty function... and now Firefox is complaining:
Error: jsonpCallback was not called
and this is immediately followed by an ajax parseerror where jqXHR.responseText = undefined.
And I see now that Chrome is logging that parseerror -> undefined as well.
Can anybody provide any guidance on this? I guess my focus right now should be on this 'jsonpCallback' thing. I thought I needed that returned from the backend, so as to "fool" the browser into thinking it was getting Javascript and not data from some remote server.
And then, on the front-end side, I needed to set those jsonp and jsonpCallback variables in the ajax request. But I THOUGHT an actual callback function, as defined with that jsonpCallback variable, was NOT necessary?
Thanks!
-= Dave =-
Dave, remove the "jsonpCallBack" key from the options you setted for jQuery.Ajax.
As seen from http://api.jquery.com/ajax ,
It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling.
Help, if you can-
The situation:
http://foobar.com includes a remotely hosted javacript file (http://boobar.com/stuff.js).
The goal is to just get an alert from the remotely hosted php script on foobar.com
I have tried the following code in stuff.js:
$.ajax({
type: "GET",
url: "http://www.boobar.com/script.php?callback=?",
dataType: 'jsonp',
success: function(result) { alert(result); }
});
No luck.
$.getJSON("http://www.boobar.com/script.php?jsonp=?",
function(data) { alert(data); }
);
Also no luck.
On the php side I have tried both the following:
return json_encode(array(0 => 'test'));
echo json_encode(array(0 => 'test'));
In Firefox I get a security error. I understand that it thinks I'm violating the security model. However, according to the jquery documentation, I should be able to accomplish this.
The error seems to be a security feature of the Same Origin Policy: to simplify, you can only make AJAX requests for stuff on the originating server (http://foobar.com). One way around this is to make a simple facade on the originating server, e.g.:
<?php
// this file resides at http://foobar.com/getstuff.php
echo file_get_contents('http://www.boobar.com/script.php?callback=?'
. $possibly_some_other_GET_parameters );
?>
Then, from foobar.com, you can make an AJAX request for http://foobar.com/getstuff.php (which in turn makes a HTTP GET request from your web server to boobar.com and sends it back to the browser).
To the browser, the request goes to the origin server, and is allowed (the browser has no way of knowing that the response comes from somewhere else behind the scene).
Caveats:
the PHP config at foobar.com must have allow_url_fopen set to "1". Although this is the default setting, some servers have it disabled.
the request to www.boobar.com is made from foobar.com server, not from the browser. That means no cookies or user authentication data are sent to www.boobar.com, just whatever you put into the request URL ("$possibly_some_other_GET_parameters").
You can get data from another server asynchronously using script tags and json:
<script type="text/javascript" src="http://somesite.com/path/to/page/"></script>
You can use this to dynamically load a remote javascript (by created a new script element and setting the src attribute, then loading into the DOM), which could set a variable. However, you need to really trust the remote site, because the JS will be evaluated without any precondition.
There is a method called window.name transport or window.name method which uses a general browser bug(not sure if this is a bug actually). You make the request through an iFrame and the loaded page puts the information you need to the "name" property of the JavaScript window object of itself.
This method uses a "blank.htm" since it first navigates to the target page and then goes back to the blank.htm page to overcome the "same origin policy" restriction.
Dojo have implemented this and you can find a more detailed explanation here.
Also I have implemented a cross-domain XMLHttpRequest object based on this method in the library I have written which can be found here.
You may not be able to use the library since it will need 1 or 2 additional libraries which can be found here.
If you need further help in implementing it in your style, I'll try to do my best.
So what I ended up doing, since it was just a GET - no data need to be retrieved - I used JQuery to create a hidden iframe with the URL including the variables I wanted to pass set as the source. Worked like a charm. To all who provded feedback - Thanks!
How about this !! Using a php proxy.
Cross-Domain AJAX calls using PHP
http://www.phpfour.com/blog/2008/03/cross-domain-ajax-using-php/
jQuery .ajax also has a setting 'crossDomain'.
http://api.jquery.com/jQuery.ajax/
crossDomain (default: false for same-domain requests, true for cross-domain requests)
Type: Boolean
If you wish to force a crossDomain request (such as JSONP) on the same domain, set the value of crossDomain to true. This allows, for example, server-side redirection to another domain. (version added: 1.5)
Hello i have the next code:
php side:
<?php
print_r($_POST);
print_r($_GET);
die();
?>
In javascript:
voteAjax = function(typez, actionz, idz){
new Ajax.Request(
'http://localhost/reporeade/Vote/Ajax/?rand='+Math.random()*500000,
{asynchronous:true,
evalScripts:true,
method:'post',
parameters:'contentType='+typez+'&action='+actionz+'&id='+idz
});
return false;
}
And in some part of my html:
<a class="button" onclick="voteAjax('content','up','89');">
You can see im running on localhost... the problem i have is that the POST somehow gets mixed up SOMETIMES, i get the next answer 90% of the time:
Array
(
[contentType] => content
[action] => up
[id] => 89
)
Array
(
[rand] => 449701.9597706424
)
And the other 10% of the time i get:
Array
(
)
Array
(
[rand] => 468905.44804602925
)
Now, i have tried everything, changed computer, tried on a server with a full url(thinking maybe localhost was the trouble), read somewhere that using http://localhost/reporeade/Vote/Ajax/?rand= instade of http://localhost/reporeade/Vote/Ajax?rand= solved the trouble but tried both and really cant undertand what would make the post get lost.... any ideas?
Edit:
Well after playing with all this, i got it working(like it is) in our production server, but in all of our wamp instalations it will not work(well fail like 50% of the time). Its really important for me to solve this so we can keep on developing all the ajax functionality of the product, so...
I tried xampp but its not compatible with our framework
I tried going to apache 2.0 instead of 2.2 in wamp
I tried with diferent configurations of the httpd.conf and php.ini
Any ideas of why wamp would fail like this?
Update:
I'm sure the problem is the wamp instalation that is not sending the POST correctly some times, any help that would lead to solving this will get the correct answer and the bounty!
I'd suggest installing WireShark and monitoring your HTTP traffic to see if you can isolate the problem that way.
Have you tried another version of Prototype? It seems to me, there's a weird bug in constructing the post request body effectively creating invalid (partly) request the server cannot properly parse. Use Fiddler (easy to grasp http sniffer) and see what exactly is being sent to the server.
If this is not the case (I admit it would be really weird if Prototype would be broken), try reading raw post data via the PHP (should be enabled in php.ini). If you can and they are not populated into the $_POST collection, try $_REQUEST instead.
Also, try to consult the following thread, maybe this is your case: http://bugs.php.net/bug.php?id=41349 .
This is a long shot, but without more information and seeing more of your code I have to ask this so you could rule it out: Could it have something to do with the user double-clicking on the link and creating two rapid requests? (Once upon a time I got bitten by <input type="image" onclick="submit();"> both run the onclick and submitted the form)
function test() {
voteAjax('content','up','89');
voteAjax('content','up','89');
}
(have your link call the test function above)
Normally you want to use asynchronous connections since that won't lock the UI, however this is a case where you could try synchronous to make sure you only do one request at the time. (a nonblocking solution is to set a flag or disable the link/button while the request is processed)
BTW, I too suggest that you send an object instead of a string as the parameters, since prototype will URIEncode it and put all & at the right places.
I also suggest you should monitor your network traffic through Wireshark:
Start it on either server or client.Start capturing your network interface.Use the AJAX andwhen it fails stop the capture andtype http in Wireshark to help you find the request.Right-click and select "Follow TCP Stream".
If POST data in the request does not show up it's something with the browser. You could check HTTP headers for possible errors (like GZip in conjunction with IE has been mentioned before).
Maybe your WAMP setup uses Fast-CGI or similar to call PHP, so it is not using the actual PHP module for Apache? Sometimes this can cause such errors if not set up correctly. If you do not necessarily need it I recommend switching to PHP module or look for possible configuration mistakes.
What WAMP is it, anyway? Pre-configured or custom?
Try new Date(), instead of random:
voteAjax = function(typez, actionz, idz){
new Ajax.Request(
'http://localhost/reporeade/Vote/Ajax/',
{asynchronous:true,
evalScripts:true,
method:'post',
parameters:'contentType='+typez+'&action='+actionz+'&id='+idz+'&now='+new Date()
});
//alert("params" + typez.toString() + actionz.toString() + idz.toString());
return false;
}
try this:
voteAjax = function(typez, actionz, idz){
new Ajax.Request(
'http://localhost/reporeade/Vote/Ajax/',
{
parameters: {
contentType: typez,
action: actionz,
id: idz,
rand: new Date()
}
});
return false;
}
notice that I've removed the other options since they aren't necesary, due to they are on it's default values :)
asynchronous:true,
evalScripts:true, -----> this one is "evalJS" not "evalScripts" :)
method:'post',
yo can see it here http://www.prototypejs.org/api/ajax/options
hope its helps!
I'm running wampserver, too, so I just tried your code, and I could not reproduce the problem -- I always get the POST values. My install is Apache 2.2.8 and PHP 5.2.6, and I just grabbed the latest prototype.js. My wampserver configuration is pretty much the default.
+1 to Fiddler and/or Firebug. Looking at the raw headers that are being sent will probably be enlightening!
What browser are you using? This fails when using FF and IE? Or only one browser.
Sometime ago I read about IE and Apache gzip module problems. It was occurring only on local installations where a server response was very fast. However your case is different.
It is definitely worth trying WireShark as others already suggested. It isn't that hard. At least you'll known on which side there is a bug.
If its a POST request you don't need to set the rand parameter, POST isn't cached, maybe that helps.
EDIT Can't really understand what's causing this without seeing more code in detail. What I would do is:
1) Try passing an object to the parameters attribute like this:
parameters: {
contentType, typez,
action: actionz,
id: idz
}
instead of a string:
parameters:'contentType='+typez+'&action='+actionz+'&id='+idz
2) Why do you need evalScripts ? For purpose of testing remove it.
3) Debug the hell out of this, seems like the problem is with the parameters being sent with Javascript, so use Firebug's console.log() to debug this more in depth.
Maybe some component where the request passes through (Php, webserver, firewall, ...) gets confused that you use a POST request with GET parameters. Does it change anything if you leave out the ?rand=... part?
What happens if you use a GET instead. I mean, if you concatenate the other parameters in the URL too? Like this
voteAjax = function(typez, actionz, idz){
new Ajax.Request(
'http://localhost/reporeade/Vote/Ajax?'+'contentType='+typez+'&action='+actionz+'&id='+idz+'&now='+new Date(),
{asynchronous:true,
evalScripts:true,
method:'post',
parameters:''
});
return false;
}
I think you can use GET.
Hope this help.
I'd do the Ajax call like this:
voteAjax = function(typez, actionz, idz){
var rndVal = Math.random()*500000;
new Ajax.Request( 'http://localhost/reporeade/Vote/Ajax/', {
method: 'post',
parameters: {contentType: typez, action: actionz, id: idz, rand: rndVal},
onSuccess: function(response) {
//do stuff
},
onFailure: function() {
alert('Something went wrong.');
}
});
return false;
}