Simple Ajax call with result handler does not work - javascript

I got this JS:
<script>
jQuery(document).ready(function(){ // we wait until DOM is ready
jQuery('#veranstort').change(function(){ // fire when input is filled
origin = "55767 Schwollen";
destination = "13509 Berlin";
jQuery.ajax({ // we build the AJAX request
method:"POST",
url:"index.php?option=com_rsform&formId=6&action=ajax",
data: {origin, destination},
success: function(results) {
console.log("results: " + results);
}
});
});
})
</script>
which fires this php script:
$action = JRequest::getWord('action'); // we will need a parameter to run the script
if ($action == "ajax") { // if condition is met, run the script
$origin = $_POST['origin']; // get the origin
$destination = $_POST['destination']; // get the destination
var_dump("destination: ".$destination); // this gives me NULL!!
$distance = file_get_contents("https://maps.googleapis.com/maps/api/distancematrix/json?origins=".$origin."&destinations=".$destination."&key=GMAPSKEY"); // build the URL according to the API
$distance = json_decode($distance); // decode the response from JSON
print_r($distance->rows[0]->elements[0]->distance->text);die(); // print the result so we can catch it in the AJAX call
}
This has worked for a while, but now it does not. I cant access the destination or origin value in php.. What am I doing wrong?

The Error came from the missing / in the URL. It got redirected, and the POST data got lost with this process.
correct URL:
url:"/index.php?option=com_rsform&formId=6&action=ajax"

Script file it's fine . Please change the ajax file condition.
$action = $_GET['action'];
if ($action == "ajax") { // if condition is met, run the script
//// Here process your code
}

Related

mimicing jsonp in javascript

<script>
window.addEventListener('load',function(){
var unique_code="3412313ad"// Initialize it with the unique code provided to you.
var param1="1"; // Initialize this with the value that you wish to see.For example 1 for navbar display , 2 for the side floating pop up
//while 3 for a transparent overlay on the whole page.
var domain=window.location.hostname;// current domain.
function jsonp(url, callback) {
var callbackName = 'jsonp_callback_' + Math.round(100000 * Math.random());
window[callbackName] = function(data) {
delete window[callbackName];
document.body.removeChild(script);
callback(data);
};
var script = document.createElement('script');
script.src = url + (url.indexOf('?') >= 0 ? '&' : '?') + 'callback=' + callbackName;
document.body.appendChild(script);
script.onerror=function(){
alert("failed to load snippet!");
}
}
jsonp('http://localhost/server.php?unique_code='+unique_code+'&domain='+domain, function(data) {
alert(data);
if(data.status=='success'){
alert('success');
}else alert(data.reason);
});
});
</script>
This is a code that mimics jsonp of the jquery to get a script from the remote server.
I used the answer given in this question JavaScript XMLHttpRequest using JsonP
Server side code would be
if(isset($_GET['unique_code']) && !empty($_GET['unique_code']) && isset($_GET['domain']) && !empty($_GET['domain'])){
$unique_code=$_GET['unique_code'];
$domain=$_GET['domain'];
$statement=$mysqli->prepare('select * from `snippet_users` where unique_code=? AND domain=?');
$statement->bind_param('ss',$unique_code,$domain);
if(!$statement->execute())
die(json_encode(array('status'=>'error','reason'=>'Server error.')));
$result=$statement->get_result();
if(mysqli_num_rows($result)>0)
die (json_encode(array('status'=>'success')));
else die(json_encode(array('status'=>'error','reason'=>'Unique code/Domain error.')));
}else{
die(json_encode(array('status'=>'error','reason'=>'Unique code/Domain error.')));
}
Everything is working perfectly fine but i see error in the console , somewhat like this :
What would be my solution so that i dont get this error as well as i get my data in the alert box?
You are outputting application/json instead of application/javascript, so your browser thinks it's not valid. The json should be in a function call (callback parameter). The callback parameter should be validated on the server side however to prevent xss injection:
Is it necessary to validate or escape the jsonp callback string

Passing a JavaScript value to PHP on completion of quiz

I have a web page that allows users to complete quizzes. These quizzes use JavaScript to populate original questions each time it is run.
Disclaimer: JS Noob alert.
After the questions are completed, the user is given a final score via this function:
function CheckFinished(){
var FB = '';
var AllDone = true;
for (var QNum=0; QNum<State.length; QNum++){
if (State[QNum] != null){
if (State[QNum][0] < 0){
AllDone = false;
}
}
}
if (AllDone == true){
//Report final score and submit if necessary
NewScore();
CalculateOverallScore();
CalculateGrade();
FB = YourScoreIs + ' ' + RealScore + '%. (' + Grade + ')';
if (ShowCorrectFirstTime == true){
var CFT = 0;
for (QNum=0; QNum<State.length; QNum++){
if (State[QNum] != null){
if (State[QNum][0] >= 1){
CFT++;
}
}
}
FB += '<br />' + CorrectFirstTime + ' ' + CFT + '/' + QsToShow;
}
All the Javascript here is pre-coded so I am trying my best to hack it. I am however struggling to work out how to pass the variable RealScore to a MySql database via PHP.
There are similar questions here on stackoverflow but none seem to help me.
By the looks of it AJAX seems to hold the answer, but how do I implement this into my JS code?
RealScore is only given a value after the quiz is complete, so my question is how do I go about posting this value to php, and beyond to update a field for a particular user in my database on completion of the quiz?
Thank you in advance for any help, and if you require any more info just let me know!
Storing data using AJAX (without JQuery)
What you are trying to do can pose a series of security vulnerabilities, it is important that you research ways to control and catch these if you care about your web application's security. These security flaws are outside the scope of this tutorial.
Requirements:
You will need your MySQL database table to have the fields "username" and "score"
What we are doing is writing two scripts, one in PHP and one in JavaScript (JS). The JS script will define a function that you can use to call the PHP script dynamically, and then react according to it's response.
The PHP script simply attempts to insert data into the database via $_POST.
To send the data to the database via AJAX, you need to call the Ajax() function, and the following is the usage of the funciton:
// JavaScript variable declarations
myUsername = "ReeceComo123";
myScriptLocation = "scripts/ajax.php";
myOutputLocation = getElementById("htmlObject");
// Call the function
Ajax(myOutputLocation, myScriptLocation, myUsername, RealScore);
So, without further ado...
JavaScript file:
/**
* outputLocation - any HTML object that can hold innerHTML (span, div, p)
* PHPScript - the URL of the PHP Ajax script
* username & score - the respective variables
*/
function Ajax(outputLocation, PHPScript, username, score) {
// Define AJAX Request
var ajaxReq = new XMLHttpRequest();
// Define how AJAX handles the response
ajaxReq.onreadystatechange=function(){
if (ajaxReq.readyState==4 && xml.status==200) {
// Send the response to the object outputLocation
document.getElementById(outputLocation).innerHTML = ajaxReq.responseText;
}
};
// Send Data to PHP script
ajaxReq.open("POST",PHPScript,true);
ajaxReq.setRequestHeader("Content-type","application/x-www-form-urlencoded");
ajaxReq.send("username="username);
ajaxReq.send("score="score);
}
PHP file (you will need to fill in the MYSQL login data):
<?php
// MYSQL login data
DEFINE(MYSQL_host, 'localhost');
DEFINE(MYSQL_db, 'myDatabase');
DEFINE(MYSQL_user, 'mySQLuser');
DEFINE(MYSQL_pass, 'password123');
// If data in ajax request exists
if(isset($_POST["username"]) && isset($_POST["score"])) {
// Set data
$myUsername = $_POST["username"];
$myScore = intval($_POST["score"]);
} else
// Or else kill the script
die('Invalid AJAX request.');
// Set up the MySQL connection
$con = mysqli_connect(MYSQL_host,MYSQL_user,MYSQL_pass,MYSQL_db);
// Kill the page if no connection could be made
if (!$con) die('Could not connect: ' . mysqli_error($con));
// Prepare the SQL Query
$sql_query="INSERT INTO ".TABLE_NAME." (username, score)";
$sql_query.="VALUES ($myUsername, $myScore);";
// Run the Query
if(mysqli_query($con,$sql))
echo "Score Saved!"; // Return 0 if true
else
echo "Error Saving Score!"; // Return 1 if false
mysqli_close($con);
?>
I use these function for ajax without JQuery its just a javascript function doesnt work in IE6 or below. call this function with the right parameters and it should work.
//div = the div id where feedback will be displayed via echo.
//url = the location of your php script
//score = your score.
function Ajax(div, URL, score){
var xml = new XMLHttpRequest(); //sets xmlrequest
xml.onreadystatechange=function(){
if (xml.readyState==4 && xml.status==200){
document.getElementById(div).innerHTML=xml.responseText;//sets div
}
};
xml.open("POST",URL,true); //sets php url
xml.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xml.send("score="score); //sends data via post
}
//Your PHP-script needs this.
$score = $_POST["score"]; //obtains score from POST.
//save your score here
echo "score saved"; //this will be displayed in the div set for feedback.
so call the javascript function with the right inputs, a div id, the url to your php script and the score. Then it will send the data to the back end, and you can send back some feedback to the user via echo.
Call simple a Script with the parameter score.
"savescore.php?score=" + RealScore
in PHP Side you save it
$score = isset ($_GET['score']) ? (int)$_GET['score'] : 0;
$db->Query('INSERT INTO ... ' . $score . ' ...');
You could call the URL via Ajax or hidden Iframe.
Example for Ajax
var request = $.ajax({
url: "/savescore.php?score=" + RealScore,
type: "GET"
});
request.done(function(msg) {
alert("Save successfull");
});
request.fail(function(jqXHR, textStatus) {
alert("Error on Saving");
});

Jquery if statement not working even if the statement is true

I have a simple if statement where when i send this certain data to the database, i want the php code to send bake a code that tells javascript its ok to continue, but if the php script sends back a bad code, javascript is to now move forward and display a certain text or something.
The php code works fine but for some reason my javascript files would not work at all.
My javascript is suppose to ajax request to parse.php and receive the data that parse.php sends back to it, if parse.php says 200 its suppose to load in specific items.
Here is the code for one of my systems:
$(document).ready(function(){
$("#chatForm").submit(function(){
var chatHash = $("#chatHash").val();
var body = $("#chatPoster").val();
var by = $("#userBy").val();
if(chatHash != "" && body != ""){
$.post('parse.php',{chatHash: chatHash, body: body, userBy: by},function(data){
if(data == "200"){ // Right here is where its messing up
$("#chatPoster").val("");
$.get('getChatMessages.php?hash=' + chatHash,function(data2){
$(".allMsgs").html(data2);
});
} else {
alert('Critical error');
}
});
} else {
alert('Error');
}
});
});
Here is the code for the parse.php page:
$chat = new ChatSystem;
if(isset($_POST['chatHash']) && isset($_POST['body']) && isset($_POST['userBy'])){
$chat->sendMessage($_POST['userBy'],$_POST['chatHash'],$_POST['body']);
}
Here is the code from the class ChatSystem that the parse.php page is referring to:
public function sendMessage($user,$hash,$body){
global $db;
$date = date("Y-m-d");
$time = date("H:i:s");
$timestamp = "$date $time";
if(empty($user) == false && empty($hash) == false){
$db->query("INSERT INTO chat_messages VALUES('','$user','$body','$timestamp','','0','$hash')") or die("error");
echo '200';
}
}
Even though my php code works perfectly the javascript still messes up. My php code sends back 200 like i ask it to but yet the jquery messes it up
Have a look here, http://api.jquery.com/jquery.post/.
You need a second parameter to the success callback function to be able to catch the response status code.
I.E. function(data,statusCode){ // check the status code here}

Request timeout

I'm using some jQuery to display tweets but once the Twitter API limit is reached, the request is sent but just keeps loading and loading. This doesn't look good. I want to be able to determine if the request is taking too long and then obviously do stuff, like cancel the request, change the styling, etc.
So this is the code that sends the request:
var fileref = document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", "http://search.twitter.com/search.json?q="+buildString+"&callback=TweetTick&rpp=50");
document.getElementsByTagName("head")[0].appendChild(fileref);
And this is the TweetTick function:
function TweetTick(ob)
{
var container=$('#tweet-container');
container.html('');
$(ob.results).each(function(el){
/* in here, a div is built for each tweet and then appended to container */
});
container.jScrollPane(); /* just adds the scrollbar */
}
You need to cache twitter api response on your server side.
How do I keep from running into the rate limit?
I had a very similar problem lately. I use this script by Remy Sharp for most of my twitter requests: http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/
What you need to realise is that the api timeout is per IP address. So if the api has timed out for you based on your testing, it won't have timed out for someone else on a different IP address. Now, if someone accessing the site is doing so within a corporation or business, and others in the same place are doing the same, that timeout will occur almost instantaneously.
To get around this you need to cache your results. The way I did this was as follows.
I created a twitter caching system using the following code:
$twitter_username = "tadywankenobi"; //
$number_of_tweets = "10";
$options[CURLOPT_URL] = 'http://api.twitter.com/1/statuses/user_timeline.xml?screen_name='.$twitter_username.'&count='.$number_of_tweets.'&include_rts=1';
$options[CURLOPT_PORT] = 80;
$options[CURLOPT_FOLLOWLOCATION] = true;
$options[CURLOPT_RETURNTRANSFER] = true;
$options[CURLOPT_TIMEOUT] = 60;
$tweets = cache($options);
$twxml = new SimpleXMLElement($tweets);
echo "<ul>";
for($i=0;$i<=($number_of_tweets-1);$i++){
$text = $twxml->status[$i]->text;
echo "<li>".auto_link_twitter($text)."</li>";
}
echo "</ul>";
function cache($options) {
$cache_filename = "/var/cache/tweets.xml";
if(!file_exists($cache_filename)){
$handle = fopen($cache_filename, 'w') or die('Cannot open file: '.$my_file);
fclose($handle);
}// Check if cache file exists and if not, create it
$time_expire = filectime($cache_filename) + 60*60; // Expire Time (1 hour) // Comment for first run
// Set time to check file against
if(filectime($cache_filename) >= $time_expire || filesize($cache_filename) == 0) {
// File is too old or empty, refresh cache
$curl = curl_init();
curl_setopt_array($curl, $options);
$response = curl_exec($curl);
curl_close($curl);
if($response){
file_put_contents($cache_filename, $response);
}
else{
unlink($cache_filename);
}
}else{
$response = file_get_contents($cache_filename);
}
return $response;
}
What the cache function at the end does is create a file on the server and stores the twitter xml feedback in there. The system then checks to see the age of that file and if it's younger than an hour old, it takes its results from there. Otherwise, it re-accesses twitter. You need to have the file writable in the /var/cache folder (create it if it's not there).
I've kinda hacked this code together a bit, so let me know if you run into any issues with it. It also uses an auto_link_twitter() function, which creates the links required within the twitter text. I didn't write that, so I'll try and find you a link to it now.
Hope that all helps,
T
UPDATE: I can't remember where I got the auto_link_twitter() function, so here it is. If the person who wrote it reads this post, my apologies, I couldn't find the source again.
function auto_link_twitter($text) {
// properly formatted URLs
$urls = "/(((http[s]?:\/\/)|(www\.))?(([a-z][-a-z0-9]+\.)?[a-z][-a-z0-9]+\.[a-z]+(\.[a-z]{2,2})?)\/?[a-z0-9._\/~#&=;%+?-]+[a-z0-9\/#=?]{1,1})/is";
$text = preg_replace($urls, " <a href='$1'>$1</a>", $text);
// URLs without protocols
$text = preg_replace("/href=\"www/", "href=\"http://www", $text);
// Twitter usernames
$twitter = "/#([A-Za-z0-9_]+)/is";
$text = preg_replace ($twitter, " <a href='http://twitter.com/$1'>#$1</a>", $text);
// Twitter hashtags
$hashtag = "/#([A-Aa-z0-9_-]+)/is";
$text = preg_replace ($hashtag, " <a href='http://twitter.com/#!/search?q=%23$1'>#$1</a>", $text);
return $text;
}
You can use specific jQuery methods to make a JSONP request. There is basic $.ajax method and shorthand method $.getJSON which fits better for you. To control timeout of the request you can use timeout parameter. Request exceeded timeout can be processed using the error callback.
$.ajax(
dataType: 'jsonp',
url: 'http://search.twitter.com/search.json',
data: {
q: buildString,
rpp: 50
},
jsonpCallback: 'TweetTick',
timeout: 30000,
error: function(jqXHR, textStatus, errorThrown) {
if (textStatus == 'timeout') {
alert('timeout exceeded');
}
}
);

How to check if page exists using JavaScript

I have a link: Hello.
When someone clicks the link I'd like to check via JavaScript if the page the href-attribute points to exists or not. If the page exists the browser redirects to that page ("www.example.com" in this example) but if the page doesn't exist the browser should redirect to another URL.
It depends on whether the page exists on the same domain or not. If you're trying to determine if a page on an external domain exists, it won't work – browser security prevents cross-domain calls (the same-origin policy).
If it is on the same domain however, you can use jQuery like Buh Buh suggested. Although I'd recommend doing a HEAD-request instead of the GET-request the default $.ajax() method does – the $.ajax() method will download the entire page. Doing a HEAD request will only return the headers and indicate whether the page exists (response codes 200 - 299) or not (response codes 400 - 499). Example:
$.ajax({
type: 'HEAD',
url: 'http://yoursite.com/page.html',
success: function() {
// page exists
},
error: function() {
// page does not exist
}
});
See also: http://api.jquery.com/jQuery.ajax/
A pretty good work around is to proxy. If you don't have access to a server side you can use YQL. Visit: http://developer.yahoo.com/yql/console/
From there you can do something like: select * from htmlstring where url="http://google.com". You can use the "REST query" they have on that page as a starting point for your code.
Here's some code that would accept a full URL and use YQL to detect if that page exists:
function isURLReal(fullyQualifiedURL) {
var URL = encodeURIComponent(fullyQualifiedURL),
dfd = $.Deferred(),
checkURLPromise = $.getJSON('http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20htmlstring%20where%20url%3D%22' + URL + '%22&format=json');
checkURLPromise
.done(function(response) {
// results should be null if the page 404s or the domain doesn't work
if (response.query.results) {
dfd.resolve(true);
} else {
dfd.reject(false);
}
})
.fail(function() {
dfd.reject('failed');
});
return dfd.promise();
}
// usage
isURLReal('http://google.com')
.done(function(result) {
// yes, or request succeded
})
.fail(function(result) {
// no, or request failed
});
Update August 2nd, 2017
It looks like Yahoo deprecated "select * from html", although "select * from htmlstring" does work.
Based on the documentation for XMLHttpRequest:
function returnStatus(req, status) {
//console.log(req);
if(status == 200) {
console.log("The url is available");
// send an event
}
else {
console.log("The url returned status code " + status);
// send a different event
}
}
function fetchStatus(address) {
var client = new XMLHttpRequest();
client.onreadystatechange = function() {
// in case of network errors this might not give reliable results
if(this.readyState == 4)
returnStatus(this, this.status);
}
client.open("HEAD", address);
client.send();
}
fetchStatus("/");
This will however only work for URLs within the same domain as the current URL. Do you want to be able to ping external services? If so, you could create a simple script on the server which does your job for you, and use javascript to call it.
If it is in the same domain, you can make a head request with the xmlhttprequest object [ajax] and check the status code.
If it is in another domain, make an xmlhttprequest to the server and have it make the call to see if it is up.
why not just create a custom 404 handler on the web server? this is probably the more "good-bear" way to do this.
$.ajax({
url: "http://something/whatever.docx",
method: "HEAD",
statusCode: {
404: function () {
alert('not found');
},
200: function() {
alert("foundfile exists");
}
}
});
If you are happy to use jQuery you could do something like this.
When the page loads make an ajax call for each link. Then just replace the href of all the links which fail.
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js"></script>
<script type="text/javascript">
<!--
$.fn.checkPageExists = function(defaultUrl){
$.each(this, function(){
var $link = $(this);
$.ajax({
url: $link.attr("href"),
error: function(){
$link.attr("href", defaultUrl);
}
});
});
};
$(document).ready(function(){
$("a").checkPageExists("default.html");
});
//-->
</script>
You won't be able to use an ajax call to ping the website because of same-origin policy.
The best way to do it is to use an image and if you know the website you are calling has a favicon or some sort of icon to grab, you can just use an html image tag and use the onerror event.
Example:
function pingImgOnWebsite(url) {
var img = document.createElement('img');
img.style.visibility = 'hidden';
img.style.position = 'fixed';
img.src = url;
img.onerror = continueBtn; // What to do on error function
document.body.appendChild(img);
}
Another way to do this is is with PHP.
You could add
<?php
if (file_exists('/index.php'))
{
$url = '/index.php';
} else {
$url = '/notindex.php';
}
?>
And then
<a href="<?php echo $url; ?>Link</a>

Categories