I have an issue with the Internet Explorer/EDGE browser. Basically, I have a script that pulls data from a remote XML file and displays it in page (live example: http://www.oldiesplus.com/ - The Radio info section, top of the page)
The way it works is that every 15 seconds, the XML file is read and the Song Title is updated (that's the scrolling bit). This works perfectly in Google Chrome, under IE/EDGE, however, the script executes (see Console log) but the element is never updated.
The XML file is grabbed using Curl and CURLOPT_FRESH_CONTENT is set to true.
The question being then, why is the element not updating with the new content in IE/EDGE?
Here's some code to help:
sc_conn.inc (PHP):
$ch = curl_init($sc_host . '/admin.cgi?mode=viewxml');
curl_setopt($ch, CURLOPT_PORT, $sc_port);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $sc_admin.':'.$sc_pass);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, TRUE);
$curl = curl_exec($ch);
shoutcast.js (JavaScript):
function getStreamData() {
var ajax;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
} else {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
ajax.open('GET','/sc_data.php', true);
ajax.send();
ajax.onreadystatechange = function() {
if (ajax.readyState == 4 && ajax.status == 200) {
var data = ajax.responseText.split("|");
var song = (data[1] == '') ? 'some music.' : data[1];
var cta = (player_state == 0) ? '/new/img/play.png' : '/new/img/pause.png';
if (data[2]) {
document.getElementById('radio-info').innerHTML = '<h2>'+data[2]+'</h2>';
document.getElementById('radio-info').innerHTML += '<p><span class="dj_name">'+data[0]+' is playing</span> '+song+'</p>';
}else{
document.getElementById('radio-info').innerHTML = '<p><span class="dj_name">'+data[0]+' is playing</span> '+song+'</p>';
}
document.getElementById('tunein').src = cta;
console.log("Title Updated!");
}
}
}
The resolution was to circumvent caching of the AJAX request - appending a random number to the end of the call of the PHP script using:
Math.random();
Related
I wrote a PHP application that makes an AJAX call (XMLHttpRequest) and is called every 5 seconds. The page called makes a database query. However, I need a variable from the main page and am unable to find a solution to attach it to the Ajax call.
Using $_GET seems a bit too insecure to me. Is there another way here?
This is my first expierence with ajax so please dont be to hard with me :)
Here is my Ajax Call
const interval = setInterval(function() {
loadText() }, 5000);
function loadText(){
//XHR Objekt
var xhr = new XMLHttpRequest();
// OPEN
xhr.open('GET', 'ajax/table_view.php?role=<?php echo $role.'&name='.$_SESSION['name'].'&org='.$_SESSION['org'];?>', true);
xhr.onload = function() {
if(this.status == 200){
document.getElementById('table_view_div').innerHTML = this.responseText; }
})
if(this.status == 404){
document.getElementById('apps').innerHTML = 'ERROR';
}
}
xhr.send();
// console.log(xhr);
}
Ill hope i provided enough Information
WIsh u all a great weekend
You do not need sending session variables at all: those are already known to the called page, because it can share the session information of the calling page.
// OPEN
xhr.open('GET', 'ajax/table_view.php?role=<?= $role ?>'
is enough, provided that "table_view.php" issues a session_start() command.
I have fixed your code; It's here:
(Note: \' means that the character ' doesn't closing the string.)
const myInterval = setInterval(function(){loadText();}, 5000);
function loadText(){
//XHR Objekt
var xhr = new XMLHttpRequest();
// OPEN
xhr.open('GET', 'ajax/table_view.php?role=<?php echo $role.\'&name=\'.$_SESSION[\'name\'].\'&org=\'.$_SESSION[\'org\']; ?>', true);
xhr.onload = function(){
if(this.status == 200){
document.getElementById('table_view_div').innerHTML = this.responseText;
}
if(this.status == 404){
document.getElementById('apps').innerHTML = 'ERROR';
}
}
xhr.send();
}
I am hoping this is a simple issue. I am using the Mailchimp API to submit a simple email signup form from my website. I am trying to learn javascript right now, so I am trying to do the httprequest and callback without jQuery. Basically, I am trying to convert this jQuery sample I found online to vanilla Javascript. But there is something (several things?) wrong with my javascript that I don't understand.
EDIT: When the form is submitted, I am taken to the email-validate.php page, and show the following error object returned by MailChimp.
{"type":"http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/","title":"Invalid Resource","status":400,"detail":"The resource submitted could not be validated. For field-specific details, see the 'errors' array.","instance":"","errors":[{"field":"","message":"Required fields were not provided: email_address"},{"field":"email_address","message":"Schema describes string, NULL found instead"}]}
jQuery
Found here (this actually throws an ajax(...).success is not a function error in the console but still submits the form, FWIW)
$('document').ready(function(){
$('.mc-form').submit(function(e){
//prevent the form from submitting via the browser redirect
e.preventDefault();
//grab attributes and values out of the form
var data = {email: $('#mc-email').val()};
var endpoint = $(this).attr('action');
//make the ajax request
$.ajax({
method: 'POST',
dataType: "json",
url: endpoint,
data: data
}).success(function(data){
if(data.id){
//successful adds will have an id attribute on the object
alert('thanks for signing up');
} else if (data.title == 'Member Exists') {
//MC wil send back an error object with "Member Exists" as the title
alert('thanks, but you are alredy signed up');
} else {
//something went wrong with the API call
alert('oh no, there has been a problem');
}
}).error(function(){
//the AJAX function returned a non-200, probably a server problem
alert('oh no, there has been a problem');
});
});
});
My Javascript (that doesn't work)
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("mc-form", function submit(e){
e.preventDefault();
var data = {"email": document.getElementById("mc-email").value};
var endpoint = document.getElementById("mc-form").getAttribute('action');
function formSubmit(callback){
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState === 4) {
if (request.status === 200) {
//Parse returned string into an object, then pass the object to the callback function.
var response = JSON.parse(request.responseText);
callback(response);
} else {
console.log('JSON request error');
}
}
}
request.open("POST", endpoint , true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.send(data);
}
function formResponse(response){
if(response.id){
//successful adds will have an id attribute on the object
alert('Thank you for signing up for Launch Alerts!');
} else if (response.title == 'Member Exists') {
//MC wil send back an error object with "Member Exists" as the title
alert('You are already signed up for Launch Alerts!');
} else {
//something went wrong with the API call
alert('Something went wrong. Please resubmit the form!');
}
}
formSubmit(formResponse);
})
});
My html
<form class="mc-form" method="POST" action="./email-validate.php">
<h2 class="launch-alerts">Never miss a launch with Launch Alerts</h2>
<label for="mc-email">Email Address:</label>
<input type="email" id="mc-email" name="mc-email" autofocus="true" required/>
<input type="text" value="pending" id="status" name="status" hidden/>
<input type="submit" value="Submit">
</form>
It uses a php file to validate and submit the form, as can be seen on the link above. The html and php work to submit the form when using the jQuery script, but not my javascript, which means there is something wrong with my script, but I am too new with javascript to fully understand what it is I am trying to do, and what I am doing wrong.
Thanks!
EDIT 2:
The PHP code (copied directly from here
<?php
//fill in these values for with your own information
$api_key = 'xxxxxxxxxxxxxxxxxxxxxxxx';
$datacenter = 'xxxxx';
$list_id = 'xxxxxxxxx';
$email = $_POST['email'];
$status = 'pending';
if(!empty($_POST['status'])){
$status = $_POST['status'];
}
$url = 'https://'.$datacenter.'.api.mailchimp.com/3.0/lists/'.$list_id.'/members/';
$username = 'apikey';
$password = $api_key;
$data = array("email_address" => $email,"status" => $status);
$data_string = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$api_key");
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json',
'Content-Length: ' . strlen($data_string))
);
$result=curl_exec ($ch);
curl_close ($ch);
echo $result;
?>
The data argument to request.send() must be a URL-encoded string, you're passing an object. jQuery does this conversion automatically for you; when you do it yourself, you have to do that yourself as well.
var data = "email=" + encodeURIComponent(document.getElementById("mc-email").value);
You're also not adding your submission function to the form's submit event correctly. It should be:
document.getElementById("mc-form").addEventListener("submit", function submit(e){
You can add URL Parameters manually to the URL:
var endpoint = document.getElementById("mc-form").getAttribute('action') +
"?email=" + document.getElementById("mc-email").value;
And then only do
request.send();
without the data in it.
What I am trying to do is upload the file/files information to upload.php using ajax, then uploading the same information again to a remote server by curl to remoteUpload.php. Finally in remoteUpload.php file I perform the actual upload of the file/files.
When doing the first step -> upload the file/files information to upload.php I display a progress bar of this step using ajax.
But the when doing the second step -> upload the same information again to remote server using curl to remoteUpload.php the progress bar is not displayed, and this is my problem.
How to display the progress bar for second step by ajax ?
Javascript:
var upload_btn = document.getElementById('upload_file');
var result = document.getElementById('result');
upload_btn.onclick = function () {
var uploadInput = document.getElementsByName('file[]')[0];
if (uploadInput.files.length > 0) {
console.clear();
var ajax = new XMLHttpRequest();
var inputFileData = formData(uploadInput);
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
var json = JSON.parse(ajax.responseText);
result.innerHTML = json.text;
}
};
ajax.upload.addEventListener('progress', function (e) {
result.innerHTML = Math.round(e.loaded / e.total * 100) + "%";
});
ajax.open("post", "upload.php");
ajax.send(inputFileData);
}
};
function formData(inputFileObj) {
var formData = new FormData;
var inputFile = inputFileObj.files;
if (inputFile.length > 0) {
for (i = 0; i < inputFile.length; i++) {
formData.append(inputFileObj.name, inputFile[i]);
}
}
return formData;
}
PHP: (upload.php)
function progressCallback($dltotal, $dlnow, $ultotal, $ulnow) {
static $last;
$progress = #round($ulnow / $ultotal * 100);
if($last < $progress) echo json_encode(array('text' => $progress));
flush();
$last = $progress;
}
if (strtolower($_SERVER['REQUEST_METHOD']) == 'post' && !empty($_FILES)) {
foreach ($_FILES['file']['tmp_name'] as $index => $tmpFileName) {
if ($_FILES['file']['error'][$index] > 0) {
$text = "A file did not uploaded correctly.";
return false;
}
$ch = curl_init("http://serverfiles/remoteUpload.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, 'progressCallback');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, array('fileupload' => '#' . $tmpFileName));
$text = curl_exec($ch);
}
}
echo json_encode(array('text' => $text));
exit;
PHP: (remoteUpload.php)
if (move_uploaded_file($_FILES['fileupload']['tmp_name'], "files/" . $_FILES['fileupload']['name']))
echo "The file has been uploaded.";
else
echo "error";
You can save in progressCallback() to $_SESSION your $progress and from js side after "first step" upland complete run setIntevral(/*ajax*/) make ajax requests to server get $_SESSION['progress] and display second progress bar(or load first progress barr till 50% and continue load second 50%) in your form and when it complete call clearInterval()
DETAILED ANSWER
Explanation: we will count progress in following logic. If we have uploaded 5 files at once (as in your case seems uploaded was multi file) then we will divide 100% by 5 and will increase by 25% progress during one file curl submit, for this you need following 5 modifications
1) call somewhere above session_start() in your upload.php if it not done
2) save to session total files count and current processing file index
// Saveing total amount of uploaded files
$_SESSION['UP_total_count'] = count($_FILES['file']);
foreach ($_FILES['file']['tmp_name'] as $index => $tmpFileName) {
...
// Saving current index of uploaded file
$_SESSION['UP_current_index'] = ($index+1);//+1 as it starts from 0
}
3) save in progressCallback function current progress number in 0-100 format
function progressCallback($dltotal, $dlnow, $ultotal, $ulnow) {
...
$_SESSION['UP_current_progress'] = $progress;
}
4) create new getUploadProgress.php and return json encoded progress infromation from session
session_start();
echo json_encode( array(
'total_count' => $_SESSION['UP_total_count'],
'current_index' => $_SESSION['UP_current_index'],
'current_progress' => $_SESSION['UP_current_progress'],
) );
5) add in your ajax.onreadystatechange setInteval function call, and define in your js global variable progressSetInterval
....
var progressSetInterval = null;// Global
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
...
progressSetInterval = setInterval(function(){
$.ajax({
type: "POST",
url: "getUploadProgress.php",
success: function(data){
// Calculating progress based on 100 25 logic explained above
var progressPart = 100 / data['total_count'];
var currProgress =
(data['total_count'] - data['current_index']) * progressPart;
currProgress += (progressPart/100) * data['current_progress'];
// You can display progress somehow, apped to div or show prgoress...
console.log( "Second progress: " + currProgress);
// if currProgress is 100% removing setinterval
if( currProgress >= 100 ){
clearInterval( progressSetInterval );
}
},
dataType: 'json'
});
}, 1000);
}
};
NOTE: during usage of this example code of course there will be needed additional rounds, JS/PHP functions addition, variable adjustments or some logical adjustments for more effectiveness, but basically this is logic of one option which you can use
My site checks 5 different URLs using PHP's cURL to tell if they're online. The problem is that it takes too long to load the page (especially if one of the sites it's checking is down).
I hear jQuery's ajax would work well, so I tried this code:
<div class="alert alert-info" id="forum-blockland-us"><b>Checking...</b></div>
<script>
$.ajax({ type: "GET",
url: "http://forum.blockland.us/",
cache:false,
success: function() {
$("#forum-blockland-us").addClass("alert-success");
$("#forum-blockland-us").removeClass("alert-info");
$("#forum-blockland-us").html("<b>Online</b>");
},
error: function() {
$("#forum-blockland-us").addClass("alert-danger");
$("#forum-blockland-us").removeClass("alert-info");
$("#forum-blockland-us").html("<b>Offline</b>");
}
});
</script>
But it always returns the error, even when I know 100% that the sites are online.
If the site is remote, there are many chances you won't be able to achieve it with javascript due to the Same Origin Policy.
However, in php, you could make only a HEAD request so it doesn't load contents so it will be much, much faster.
Hope this helps. Cheers
As #Edgar said, you better do it by php, and if you want to, this is how :
function urlExists($url=NULL)
{
if($url == NULL) return false;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
$httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if($httpcode>=200 && $httpcode<300){
return true;
} else {
return false;
}
}
Source
I need to find out if a page is returning a 404 or 301 status code. I know I can write a php script to use cURL to return a value for javascript to read, but I am trying to simplify the process and kinda new. Right now I have an onBlur function that makes sure the webpage is at least in the correct format before they leave the field. But I would like it to also check the status of the page and I can't seem to find a solution for using cUrl directly with javascript or any examples of how this would be done. Anybody care to help me out please? Here is my validate.js that I am calling on the page...
function loadXMLDoc() {
var url = document.getElementById("webpage_url").value;
var xmlhttp;
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("valid").innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("GET", "custom/modules/CT221_SEP_test/js/curltest.php/" + url, true);
xmlhttp.send();
}
function isURL() {
var url = document.getElementById("webpage_url");
var urlerr = document.getElementById("url_error");
var reg = /http:\/\/[A-Za-z0-9\.-]{3,}\.[A-Za-z]{3}/;
if (!reg.test(url.value)) {
urlerr.innerHTML = "Invalid WebPage Address";
url.focus();
} else {
loadXMLDoc();
urlerr.innerHTML = //calls success image";
}
}
YAHOO.util.Event.on("webpage_url", "blur", isURL);
then my curltest.php file looks like this...
$url = $_GET['url'];
function validateurl($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);
preg_match("/HTTP\/1\.[1|0]\s(\d{3})/", $data, $matches);
return $matches[1];
}
$code = validateurl($url);
if ($code != "404") {
echo "Webpage is valid";
} else[
echo "Webpage is not live";
}
Sounds like a simple case of creating a PHP proxy script. The function that validates the URL could (on success) call an AJAX function to a PHP scrip, passing the URL so that you can make a cURL request to it. Instead of pinging the website directly, you could opt use some sort of DNS lookup. Upon your PHP script finishing, you can return some sort of value/data to the AJAX function which can act accordingly on the page. Chances are you will need to use callbacks on the client and server side so as not to hang the page, unless that is preferable to them moving on with the rest of the form. Your call.