I have an ajax script that sends some data to an external URL. The external URL is hosted on the same server, however the domain is different than the source of the ajax call.
This is working perfectly in Firefox and Chrome. However in IE The ajax call does not go through, and the Return False function does not either work (once the ajax call fails).
Below is my code:
$.get('http://myexternaldomian.com/feedback/save.php', {
answer: $('#answer').val(),
page_url: pathname
});
// Keeps the user on the page
return false;
When I try removing the http:// from the ajax url, the return false does work.
Any help on this would be greatly appreciated. Thank You
From jQuery documentation
Due to browser security restrictions,
most "Ajax" requests are subject to
the same origin policy; the request
can not successfully retrieve data
from a different domain, subdomain, or
protocol.
and Same Origin Policy on Wiki
I'm surprised any of them are working. Browsers generally don't allow ajax calls to a domain other than the one the current page came from.
The main exception to this rule is if you make an ajax call using jsonp (json with padding). You can do this with jQuery, here's how. Look under the dataType option.
(this is copypaste from my another similar answer). You could try enabling "jQuery.support.cors=true" flag and see how it goes. I use jQuery v1.7.2.
I had to load webpage from local disk "file:///C:/test/htmlpage.html", call "http://localhost/getxml.php" url, and do this in IE8+ and Firefox12+ browsers, use jQuery v1.7.2 lib to minimize boilerplate code. After reading dozens of articles finally figured it out. Here is my summary.
server script (.php, .jsp, ...) must return http response header Access-Control-Allow-Origin: *
before using jQuery ajax set this flag in javascript: jQuery.support.cors = true;
you may set flag once or everytime before using jQuery ajax function
now I can read .xml document in IE and Firefox. Other browsers I did not test.
response document can be plain/text, xml, json or anything else
Here is an example jQuery ajax call with some debug sysouts.
jQuery.support.cors = true;
$.ajax({
url: "http://localhost/getxml.php",
data: { "id":"doc1", "rows":"100" },
type: "GET",
timeout: 30000,
dataType: "text", // "xml", "json"
success: function(data) {
// show text reply as-is (debug)
alert(data);
// show xml field values (debug)
//alert( $(data).find("title").text() );
// loop JSON array (debug)
//var str="";
//$.each(data.items, function(i,item) {
// str += item.title + "\n";
//});
//alert(str);
},
error: function(jqXHR, textStatus, ex) {
alert(textStatus + "," + ex + "," + jqXHR.responseText);
}
});
http://en.wikipedia.org/wiki/Same_origin_policy
I dont think it should work on Chrome or Firefox, unless you testing on localhost or something like that, this would be against the crossdomain policy.
What you need is to proxy it inside the same domain, use php to connect to the destination you need and call the url from the same domain.
save_cross_domain.php -> connect through server to the desired url
then ajax calls save_cross_domain.php
you should add a
callback=?
to your url and handle this on the server side.
I did this once for a java servlet, and when the callback param was included I added an extra pair of parenteses around the json response..
hope it helps!
A couple of things:
The answers/conversation for this question has gone a bit out of context. Actually from the question it was more implied how to make ajax calls in IE. [Atleast modify the question title, else the question is very localized]
A couple of solutions to this cross-domain issue:
CORS[compatible after IE7]
JSONP [ here actually the browser takes in the input thinking it is a script]
server side encoding
Related
I've been on this for hours already, I've read tons of articles and still cant figure it out.
Here's the deal.
I am working with Chrome extensions and I want to do a call to my server that returns me a js object. I dont want to inject this into the page, but I want to be able to use it within my content script.
NOTE: I cannot use eval() (I have tried though) and I cannot use jsonp
I am using a framework so my headers arent set here, but they set to return application-type application/javascript utf-8;
my php side looks like this:
$refererObj = 'var refererObj = {
myFunc: function () {
console.log("hello");
}
};';
echo $refererObj;
my js looks like this
$.ajax({
url: myUrl,
crossDomain: true,
data: postData,
dataType: "json",
type: "POST",
}).done(function(data){
eval(data);
console.log(data);
console.log(refererObj);
});
The first console.log gives ["var refererObj = {↵ getProducts: function () {↵…(products);↵ console.log("hello");↵ }↵};"]
The second gives "Uncaught ReferenceError: refererObj is not defined"
I get the response as a string with the javascript object and everything is all good until I actually want to "convert" the string into a usable code.
Any help would be really great.
Thanks
You actually can use eval() if you relax the default Content Security Policy with unsafe-eval. But it's a big hammer that's best avoided.
You can use JSONP, again, if you can serve it off an https server and add it to script-src of the Content Security Policy. This is slightly less of a security risk.
I doubt there is any other solution: anything you load off an external server is to be considered tainted and if you find a way to execute it - congrats, you just bypassed CSP in Chrome and should go claim your bug bounty.
Please note that in case of simply JSON data it's all moot, you can just load it with XHR and JSON.parse it. But your example contains code.
On one of my pages I have "tracking.php" that makes a request to another server, and if tracking is sucessful in Firebug Net panel I see the response trackingFinished();
Is there an easy way (built-in function) to accomplish something like this:
If ("tracking.php" responded "trackingFinished();") { *redirect*... }
Javascript? PHP? Anything?
The thing is, this "tracking.php" also creates browser and flash cookies (and then responds with trackingfinished(); when they're created). I had a JS that did something like this:
If ("MyCookie" is created) { *redirect*... }
It worked, but if you had MyCookie in your browser from before, it just redirected before "track.php" had the time to create new cookies, so old cookies didn't get overwritten (which I'm trying to accomplish) before the redirection...
The solution I have in mind is to redirect after trackingFinished(); was responded...
I think the better form in javascript to make request from one page to another, without leaving the first is with the ajax method, and this one jQuery make it so easy, you only have to use the ajax function, and pass a little parameters:
$.post(url, {parameter1: parameter1value, param2: param2value})
And you can concatenate some actions:
$.post().done(function(){}).fail(function(){})
And isntead of the ajax, you can use the $.post that is more easy, and use the done and fail method to evaluate the succes of the information recived
As mentioned above, AJAX is the best way to communicate between pages like this. Here's an example of an AJAX request to your track.php page. It uses the success function to see if track.php returned 'trackingFinished();'. If it did then it redirects the page 'redirect.php':
$.ajax({
url: "track.php",
dataType: "text",
success: function(data){
if(data === 'trackingFinished();'){
document.location = 'redirect.php';
}
}
});
The example uses JQuery.
what I need to do is read the content of a "public" google spreadsheet (by public I mean that I saved the sheet clicking on "File > Publish to the web", so it's accessible without the need to be logged in into a google account), and, why not, write something into it too.
googlin' around, I found that I can access the sheet and get the xml equivalent of the sheet content with something like
https://spreadsheets.google.com/feeds/list/<sheetCode>/od6/public/values
It works great if I load that url into a browser. But I need to find a "javascript-way" to get and handle the returned value, ie the xml (or json, but xml would be preferable).
I tried to use an ajax call, but I think there's something messy with the protocol.. I can't get the server response correctly.
$.ajax({
type: "GET",
url: "https://spreadsheets.google.com/feeds/list/<sheetCode>/od6/public/values",
success: function(data){alert("yeah");},
error: function(){alert("fail..");},
dataType:"xml",
});
I also tried to get the json instead of xml, adding "?alt=json" to the url and changing the datatype, but I still have the problem..
Any idea / suggestion?
Thanks in advance, best regards
You need to request with a JSONP call and you need to specifiy a callback - method. This can be done in jQuery using:
var url = 'https://spreadsheets.google.com/feeds/list/<CODE>/od6/public/values?alt=json-in-script&callback=?';
jQuery.getJSON(url).success(function(data) {
console.log(data);
}).error(function(message) {
console.error('error' + message);
}).complete(function() {
console.log('completed!');
});
Documentation and samples for google spreedsheets .
I am trying to pass parameters to the TinyPaste API. I have the following JQuery script in an HTML file,
$.post("http://tinypaste.com/api/create.json",
{
"paste": "This is test paste",
"title": "Test",
"is_code": 0,
"is_private": 1
},
function(data) {
console.log(data);
}
);
As seen in the Firefox's Web Console, I can see that the request is made and is successful (The content length of the response is as expected). But the callback function is not printing anything in the console window.
What am I doing wrong here?
Looks like you are making a request to another domain from your website and this violates the SAME ORIGIN POLICY of browers, you need to use JSONP to work around this..
you should write like this
$.post("http://tinypaste.com/api/create.json",
{
'paste': "This is test paste",
'title': "Test",
'is_code': 0,
'is_private': 1
},
function(data) {
console.log(data);
},
'jsonp'
);
You must send also a data type to server, means jsonp.
EDIT: POST does not work for cross domain USE $.getJSON instead
$.getJSON("http://tinypaste.com/api/create.json",
{
"paste": "This is test paste",
"title": "Test",
"is_code": 0,
"is_private": 1
},
function(data) {
console.log(data);
}
);
It is entirely possible the API does not serve JSONP, in which case you will need to resort to alternate methods
The major (and only) problem with the script posted in the question is that it is making a cross domain HTTP/POST request while on a normal webpage. I previously believed you were working on some browser extension, which if configured properly will allow you to have cross-domain requests. HTTP/POST will just not work in your case. Although there are hacks to get HTTP/GET working, like using the script tag, and JSONP.
In your case, what I suggest is let your server (which serves out your page) carry out the request for you.
The process will be:
You submit a request to the server with the parameters for tinypaste.
The server side script will do the HTTP/POST to tinypaste, and fetch the response. This response is sent across to the browser.
Browser gets the response. (and may be redirects or something)
Or as #charlietfl suggests, you could use YQL and Jquery
I have the following code I am using to send data to a MailChimp Newsletter List (API v3). Everytime I remove the type: POST from the function it attempts to post the data via GET and it sends the data properly (ok response in MailChimp API dashboard). When testing this in the browser (FF) I get a .part file with "true" response.
$(function(){
$("a#test").click(function(e){
e.preventDefault()
data = {
"apikey" : "667378947",
"id" : "90298590285",
"email_address" : "test#getmoxied.net",
"output" : "json"
}
$.ajax({
type: "POST",
url: 'http://us2.api.mailchimp.com/1.3/?method=listSubscribe',
data: data,
success: function(data){
alert(data);
},
error: function(){
alert("err");
}
})
});
});
Im pulling my hair out on this one, any insight is greatly appreciated.
Thanks in advance,
JN
There is an undocumented endpoint that uses JSONP to do cross-domain ajax requests.
Just change 'post?' to 'post-json?' and add '&c=?' to the end of the standard url to get the JSONP endpoint. This doesn't requires the API key to be exposed on the client-side, or the creation of a server-side view.
I wrote a jQuery plugin that uses this method, if that's useful at all
https://github.com/scdoshi/jquery-ajaxchimp
The main issue is what jc commented on your original post - this simply won't work due to Same Origin Policy issues. Firebug is not as vocal about why the GET call fails, but that's why it returns no data. If you watch that with the POST, you'll see Firefox doesn't even make the call. Chrome's js console on the other hand straight explains the Same Origin policy to you.
All in all, this is a very good thing if for no other reason than it prevents you from publicly publishing your account's API Key, which is a very bad thing to do. If the reason why doesn't immediately sink in, go read through the large number of methods available in the API and then realize that all you need to access them is that API Key.
The correct way to do this is to POST data back to your server, then make the request from there. There are several fully built PHP examples (one using jquery, even), here.
e.preventDefault();
data = {
"apikey" : "667378947",
"id" : "90298590285",
"email_address" : "test#getmoxied.net",
"output" : "json"
};
Could be? Semicolon is important. Hehe