I was trying to perform client side validation for captcha. For that I need to get the response from an external url. I used the below javascript code for that.
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript">
function captcha_check()
{
var code = document.getElementById("captcha").value;
alert(code);
var url = "http://www.opencaptcha.com/validate.php?img='.$captcha_name.'.jpgx&ans="+code;
alert(url);
$.get(url,function(data,status){
alert(data);
if(data == "fail")
{
document.getElementById("captcha_error").style.display = "block";
return false;
}
else
{
return true;
}
});
}
</script>
But the code is not working. The url and code are alerting correctly. But the javascript stops executing the jquery function to get content from the url and skipping the remaining steps in the function.
Please help me find out what's wrong with my code.
Thank you all in advance.
Cross domain ajax request can't be done unless the response accept request from all domains.
Also i don't think client side validation for captcha can be called "secure".
More info:
Cross-Origin Resource Sharing (CORS)
There are security restrictions on cross domain ajax calls.
Check out http://en.wikipedia.org/wiki/Same_origin_policy
I tried a your code from my location and chrome returns:
XMLHttpRequest cannot load http://www.opencaptcha.com/validate.php?img=%27.$captcha_name.%27.jpgx&ans=hi. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://fiddle.jshell.net' is therefore not allowed access.
which is what you expect with cross domain calls like this.
This is why your code is failing.
Related
Question
I need to parse an RSS feed and display the parsed details in an HTML page.
Solution I Found
How to parse an RSS feed using JavaScript? is a very similar question and I followed it.
Using above question, I build the following code.
<script>
$(document).ready(function() {
//feed to parse
var feed = "https://feeds.feedburner.com/raymondcamdensblog?format=xml";
$.ajax(feed, {
accepts:{
xml:"application/rss+xml"
},
dataType:"xml",
success:function(data) {
//Credit: http://stackoverflow.com/questions/10943544/how-to-parse-an-rss-feed-using-javascript
$(data).find("item").each(function () { // or "item" or whatever suits your feed
var el = $(this);
document.write("------------------------");
document.write("title : " + el.find("title").text());
document.write("link : " + el.find("link").text());
document.write("description: " + el.find("description").text());
});
}
});
});
</script>
The Error
Failed to load
https://feeds.feedburner.com/raymondcamdensblog?format=xml: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
What I need
How can I change my code to read RSS feeds using JavaScript without getting above error?
You could use something like https://rss2json.com.
It parses the feed to json for javascript:
var feedURL = "https://feeds.feedburner.com/raymondcamdensblog?format=xml";
$.ajax({
type: 'GET',
url: "https://api.rss2json.com/v1/api.json?rss_url=" + feedURL,
dataType: 'jsonp',
success: function(result) {
console.log(result);
}
});
You're getting that error because of the same-origin policy. See below and/or read the full article at MDN:
For security reasons, browsers restrict cross-origin HTTP requests
initiated from within scripts. For example, XMLHttpRequest and the
Fetch API follow the same-origin policy. This means that a web
application using those APIs can only request HTTP resources from the
same origin the application was loaded from, unless the response
from the other origin includes the right CORS headers.
So your script is making a cross-origin HTTP request (which uses XMLHttpRequest through jQuery.ajax()) to https://feeds.feedburner.com/raymondcamdensblog?format=xml, but the CORS header of Access-Control-Allow-Origin is not being set by FeedBurner, therefore you get the "Failed to load ..." error. (But even if the header was set, if it didn't include your origin (localhost or some-domain.com), you'd still get the same error.)
So how can you change your code to read the RSS feeds using JavaScript without getting that error?
Use a third-party web service, just like what #Saeed suggested.
Create a server-side script (e.g. using PHP) that fetches the feed content and make AJAX requests to that script instead of directly requesting it from FeedBurner, or the actual source URL. See below for a simple example.
If I really had to, I'd probably ask FeedBurner to set the appropriate CORS headers...
Sample of a very simple PHP script for fetching the feed content:
<?php
// Set the feed URL.
$feed_url = 'https://feeds.feedburner.com/raymondcamdensblog?format=xml';
// Fetch the content.
// See http://php.net/manual/en/function.file-get-contents.php for more
// information about the file_get_contents() function.
$content = file_get_contents( $feed_url );
// Set the Content-Type header.
header( 'Content-Type: application/rss+xml' );
// Display the content and exit.
echo $content;
exit;
?>
So for example, you could save that to fetch-feed.php, and then in your JavaScript/jQuery script code, change the value of the feed variable like so:
var feed = "http://localhost/path/to/fetch-feed.php";
That way (i.e. using your own server-side script), you could at least be sure that the browser would always grant your XMLHttpRequest (or AJAX) request. (i.e. you wouldn't get the "No 'Access-Control-Allow-Origin' header" error)
You can also use jquery-rss or Vanilla RSS, which comes with nice templating and is super easy to use:
// Example for jquery.rss
$("#your-div").rss("https://feeds.feedburner.com/raymondcamdensblog?format=xml", {
limit: 3,
layoutTemplate: '<ul class="inline">{entries}</ul>',
entryTemplate: '<li>[{author}#{date}] {title}<br/>{shortBodyPlain}</li>'
})
// Example for Vanilla RSS
const RSS = require('vanilla-rss');
const rss = new RSS(
document.querySelector("#your-div"),
"https://feeds.feedburner.com/raymondcamdensblog?format=xml",
{
// options go here
}
);
rss.render().then(() => {
console.log('Everything is loaded and rendered');
});
See http://jsfiddle.net/sdepold/ozq2dn9e/1/ for a working example.
It's a CORS related error. You are getting that error because the URL from where you are requesting data does not have CORS enabled. CORS stands for 'Cross-Origin Resource Sharing'. If CORS is enabled on a server, your browser will let you make requests to that server. Otherwise, it will not.
https://feeds.feedburner.com/raymondcamdensblog?format=xml does not have CORS enabled, that's why your browser will not allow you to make ajax requests to that server. You can get around it by making the requests on your server and provide the data to the browser from your own server or a server that has CORS enabled.
I do site verification after getting g-recaptcha-response thru user verification.
I send xhr POST with parameters and get 200 OK, yet NO response as it should be:
{
"success": true|false,
"error-codes": [...] // optional
}
Code
<script type='text/javascript'>
var onReturnCallback = function(response) {
document.getElementById('resp').innerHTML = response; // works well
//alert('grecaptcha.getResponse() = ' + grecaptcha.getResponse()); // works well too
$.post("https://www.google.com/recaptcha/api/siteverify",
{ secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
response: response,
remoteip : "<?php echo $ip;?>" // optional, does not influence an empty result
}).complete(function( data ) {
alert( "Data returned from POST: " + data.toString() );
console.dir(data);
});
};
</script>
Form.
<form method="post">
<div class="g-recaptcha" data-sitekey="6LdYKQkTAAAAAD9K6-kHspFUPUnftw1RxP5_awi0" data-callback="onReturnCallback" data-theme="light"> </div>
<input name="send" type="submit" />
</form>
The object that I print in console is totally empty (except for statusText='error'), see the shot.
There is other error in console:
XMLHttpRequest cannot load https://www.google.com/recaptcha/api/siteverify. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://tarex.ru' is therefore not allowed access.
How to deal with it? Can i change the origin header? How to verify?
The link to the demo.
It is not possible to make XHRs ("AJAX requests") to hosts other than the one serving a website due to the so-called "same origin policy" (SOP) to prevent XSS attacks.
However you can post to the reCaptcha site from a php proxy, that you run on your own host. An example for this is given in this answer. This also prevents your secret from being public to people looking at your client-side source code.
Another possibility (depending on the service you want to use) is JSONP. As XHRs are prohibited, but loading scripts from foreign hosts is not, it is possible to add the name of a callback function via query parameters to the script URL. This function is then invoked as soon as the foreign resource is loaded. But as far as I know reCaptcha does not support JSONP.
reCaptcha purportedly supports jsonp as a legal value of the dataType parameter.
I'm trying to load content from one of my sites in another:
<div id='include-from-outside'></div>
<script type='text/javascript'>
$('#include-from-outside').load('http://lujanventas.com/plugins/banner/index.php&callback=?');
</script>
But I'm getting this error:
XMLHttpRequest cannot load http://lujanventas.com/plugins/banner/index.php&callback=?. Origin http://lventas.com is not allowed by Access-Control-Allow-Origin.
How can I prevent it from happening?
There are two options:
1: make http://lujanventas.com return proper CORS headers -- http://enable-cors.org/
2: request the html using your server instead of with js in the browser -- http://www.daniweb.com/web-development/php/code/216729/php-proxy-solution-for-cross-domain-ajax-scripting
The url you are using suggests the site supports JSONP (see http://en.wikipedia.org/wiki/JSONP). If so, you should be able to do it like this:
<script type="text/javascript">
function handleResponse(json){
var data = JSON.parse(json);
...handle data...
}
</script>
<script src="http://lujanventas.com/plugins/banner/index.php?callback=handleResponse"></script>
Use jquery ajax to query a php file that loads lujaventas content then the ajax callback will be lujaventas content.
I'm using the following code in order to make an ajax call to my server.
The code makes the call to the server and in return, it gets a list of all the friends that use the same app.
FB.getLoginStatus(function(response) {
if (response.session) {
uid = response.session.uid;
access_token = response.session.access_token;
$.getJSON(serverLink+"ajax.php?action=getFriendsApp", {token:access_token}
,function(data){
var temp = data;
if(true){
var container = $('#friends_part_main');
var fp = $('#friends_part');
fp.show();
var friends = data;
for(var i in friends){
container.append('<a target="_blank" href="http://www.facebook.com/profile.php?id='+friends[i]+'">\n\
<img src="https://graph.facebook.com/'+friends[i]+'/picture" alt="friend" />\n\
</a>');
}
}
});
}
If I run this code directly from the browser (www.mydomain.com/app) it works.
But when I run it from the canvas page (app.facebook.com) I get the foloowing error:
XMLHttpRequest cannot load
http://www.mydomain.com/src/ajax.php?action=getFriendsApp&token=AAAC0kxh1WAcBAHo3s0QaVy34mgdnCNGvrDZCvIQsZCBHZC8ovR9IuYEFlUKRqK0GgJosWAD6Embg8QrN07vivE6mOuAZAtxUD7WpySDL3wZDZD.
Origin https://www.mydomain.com is not allowed by
Access-Control-Allow-Origin.
Can you figure out why??
For me, the domain in the URL of my ajax page "ajax.php" and the URL of the ajax-calling-page "index.php" weren't exactly the same. "www" missed...
You have to check that your two scripts domains (the calling script and the responding script) are exacty the same ! Check the "http" vs "https", check the "https://my-domain.com" vs "https://www.my-domain.com" etc.
Hope it helps.
xxx
You need JSONP or to allow ajax requests on your domain. You can force it with
header("Allow-Access-Control-Origin:*");
Your XMLHttpRequest is not allowed by access control allow origin because facebook load your application via secure https, but you could access only http. You can't load from other sundomain, protocol or port.
Try JSONP with callback function. You can load Javascript code from any place, if your response contain not only data, but callback function, you could access any data from any place of your server (site).
So I have a bit of a problem. When I ask MooTools to send a request it comes back as failed every time. I can't seem to diagnose the problem either because if I try to get the returned header info the console just gives me "Refused to get unsafe header 'Status'" Message. The only thing I can think of is that the server isn't letting me access outside resources but maybe I just coded it wrong.
Here's the request code:
var finfo = current.textFontData();
var url = 'http://antiradiant.com/clients/TMW/rbwizard/mailer.php?s='+current.size+'&b='+current.box+'&l='+current.lidWood+'&c='+current.cartID+'&f='+finfo.font+'&l1='+finfo.line1+'&l2='+finfo.line2;
console.log(url);
var req = new Request({
url: url,
onSuccess: function() {
console.log('success');
//atc2.send();
},
onFailure: function() {
console.log('failure');
console.log(this.getHeader('Status'));
//atc2.send();
},
onException: function(headerName, value) {
console.log('exception');
console.log(headerName+': '+value);
}
});
req.send();
This code is derived from the resource rb_wizard.js (lines 81-103) on http://tylermorriswoodworking.myshopify.com/pages/recipe-box-wizard?b=maple&l=cherry&s=3x5&c=42042892
Mootools has a class called Request.JSONP that will help with your cross domain problem. Its sub class of the Request class, so your methods should work the same. I believe you need to call .post() or .get() at the end instead of send, but thats about all that should chnge. I'm not sure what version you're running on but here is the link tot he docs Mootools Request.JSONP
The error message "Refused to get unsafe header 'Status'" is spat out by WebKit based browsers (Safari, Chrome, etc) when you violate the cross-domain security model.
Therefore, it seems likely that the code you pasted is located on a domain other than antiradiant.com, and therefore is not allowed (by the browser) to request sites on antiradiant.com.
What I ended up doing was just using an iframe. All I really had to do was send data to another site and not receive any so it worked out.