XHR and php Progress bar, working on local, not on remote - php

More explanation here :
Im importing products to my DB, and everytime a product is imported I display the percent calculated earlier:
//Progress bar
set_time_limit(0);
ob_implicit_flush(true);
ob_end_flush();
sleep(1);
$p = ($i/$count_product)*100; //Progress
$response = array( 'success' => true , 'message' => $p . '% ','progress' => $p);
$i++;
echo json_encode($response);
On my local everything is working fine :
Every time php echo json_encode() I get on XHR a new state 3, and display the response.
Code below:
var xhr = new XMLHttpRequest();
xhr.previous_text = '';
$param = 'id='+$(this).find('input').val();
xhr.onerror = function() {console.log(xhr.responseText) };
xhr.onreadystatechange = function() {
//try{
console.log(xhr.readyState);
console.log(xhr);
console.log(new_response);
if (xhr.readyState == 4){
var new_response = xhr.responseText.substring(xhr.previous_text.length);
var result = JSON.parse( new_response );
if (result['message'] == '100' ) {
$('.progress_bar').html('<div><?=$this->translate->_("Imported succefully")?></div>');
$.when($('.full_screen_layer').fadeOut(2000)).done(function() {
location.reload();
});
}else{
$('.progress_bar').html('<div style="color:red">'+result['message']+'</div>');
setTimeout(function(){
$.when($('.full_screen_layer').fadeOut(2000)).done(function() {
location.reload();
});
}, 2000);
// alert('<?=$this->translate->_("Please try again")?>');
}
}
else if (xhr.readyState > 2){
var new_response = xhr.responseText.substring(xhr.previous_text.length);
var result = JSON.parse( new_response );
if (result['success'] && result['end'] == undefined) {
$('.progress_bar').html('<div>'+result['message']+'</div>');
xhr.previous_text = xhr.responseText;
}else{
$('.progress_bar').html('<div style="color:red">'+result['message']+'</div>');
}
}
//}
// catch (e){
// alert("[XHR STATECHANGE] Exception: " + e);
// }
};
xhr.open("POST", action, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send($param);
But I'm trying to understand why it's not working on the server ( XHR state 3 is fired only once, at the end of the request ( so the json is malformed )
Here are the headers:
This just break my mind, if someone have an idea, even a bad one xD
(Btw there is a proxy on the server : VIA:1.1 Alproxy ) it could stop the response untill it end and then send it alltogether ?

Related

Continuously get PHP loop data in Ajax Call

I have this codes in process.php:
$users = $_POST['users']; // Sample: "user1, user2, user5"
$users = explode(', ', $users);
$step = 0;
foreach ($users as $r) {
$user_email = get_user_email($r); // Get email of each user
if (!empty($user_email)) {
send_w_mail(); // Send email to each user
$step++;
echo json_encode(
['step' => $step, 'all' => count($users)]
); // echo output
}
}
And this is my ajax call in index.php:
$("#send-message").click(function () {
$.ajax({
url: global_base_url + 'process.php', // global_base_url defined.
async : true,
type: 'POST',
data: {'users': input_users}, // input_users is val() of a input.
encoding: 'UTF-8',
success: function (data) {
data = $.trim(data);
if (data){
data = $.parseJSON(data);
var p_value = parseInt(data.step*100)/data.all;
set_progressbar_value(p_value); // set progressbar value. sample: 23%
}
}
});
});
This codes don't have any problem for execute and showing result.
But I want to Continuously get output json data from process.php in order to show process of each $step in Percent unit in a bootstrap process-bar;
I found some function like ignore_user_abort(), ob_clean() and ob_flush() but don't know how can I solve my problem with them.
How Can I do this? Please help me to solve the problem.
Thanks a lot.
There are two ways of approaching this problem
Websocket
Long polling
I will be describing the long polling method here:
$users = $_POST['users']; // Sample: "user1, user2, user5"
$users = explode(', ', $users);
$step = 0;
foreach ($users as $r) {
$user_email = get_user_email($r); // Get email of each user
if (!empty($user_email)) {
send_w_mail(); // Send email to each user
$step++;
echo json_encode(
['step' => $step, 'all' => count($users)]
); // echo output
//Flush the output to browser
flush();
ob_flush();
}
Jquery does not provide api for XMLHttpRequest.readyState == 3 (Loading docs here) so we need to use raw XMLHttpRequest object
$("#send-message").click(function () {
var prev_response = "";
var xhr = new XMLHttpRequest();
xhr.open("POST", global_base_url + 'process.php', true);
//Send the proper header information along with the request
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {//Call a function when the state changes.
if(xhr.readyState == 3) {
// Partial content loaded. remove the previous response
var partial_response = xhr.responseText.replace(prev_response,"");
prev_response = xhr.responseText;
//parse the data and do your stuff
var data = $.parseJSON(partial_response);
var p_value = parseInt(data.step*100)/data.all;
set_progressbar_value(p_value);
}
else if(xhr.readyState == 4 && xhr.status == 200){
set_progressbar_value(100);
console.log("Completed");
}
}
xhr.send("users="+ input_users);
});

Autocomplete URL AJAX

I want to know where is gsmarena.com put ajax url when they do a search. I tried to explore the source of it and I found this function:
function autocompleteLoadList() {
if (AUTOCOMPLETE_LIST !== null) return;
AUTOCOMPLETE_LIST = false;
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest
} else if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP")
} catch (x) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP")
} catch (x) {
AUTOCOMPLETE_LIST = null
}
}
}
xhr.open("GET", AUTOCOMPLETE_LIST_URL, true);
xhr.onreadystatechange = function(e) {
if (xhr.readyState == 4)
if (xhr.status == 200) {
var data;
if (window.JSON) {
data = JSON.parse(xhr.responseText)
} else {
data = eval("(" + xhr.responseText + ")")
}
AUTOCOMPLETE_MAKERS = data[0];
AUTOCOMPLETE_LIST = data[1];
if (typeof AUTOCOMPLETE_CALLBACK != "undefined") AUTOCOMPLETE_CALLBACK()
} else {
AUTOCOMPLETE_LIST = null
}
};
xhr.send(null)
}
http://cdn2.gsmarena.com/w/js/autocomplete.js?ver=2
I do not know where they put the url to doing a search.
when I open the network tab in Google Chrome console there is also no url to POST or GET. how could they do it?

how to parse html already store in variable

I want to parse a shoutcast page like this :
http://relay.181.fm:8800/played.html
So, i just make ajax to call a php file. The php file return all the content of the page.
i store the html content to a var in js. Here is the code:
PHP:
function getcontent($server, $port, $file){
$cont = "";
$ip = gethostbyname($server);
$fp = fsockopen($ip, $port);
if (!$fp){
return "Unknown";
}
else{
$com = "GET $file HTTP/1.1\r\nAccept: */*\r\nAccept-Language: de-ch\r\n"
."Accept-Encoding: gzip, deflate\r\nUser-Agent: Mozilla/4.0 (compatible;"
." MSIE 6.0;Windows NT 5.0)\r\nHost: $server:$port\r\n"
."Connection: Keep-Alive\r\n\r\n";
fputs($fp, $com);
while (!feof($fp))
{
$cont .= fread($fp, 500);
}
fclose($fp);
$cont = substr($cont, strpos($cont, "\r\n\r\n") + 4);
return $cont;
}
}
echo (getcontent("relay.181.fm", "8800", "/played.html"));
Here is my js:
var xhr = new XMLHttpRequest();
var parsed;
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
parsed=xhr.response;
}
};
xhr.open("GET", 'http://localhost/getsong.php', true);
xhr.send(null);
And that is what i want to get:
$(document).ready(function(){
var songs=new Array();
var time=new Array();
for (var i = 0; i < 10; i++) {
songs[i]=$('table:eq(2) tr:eq('+(i+1)+') td:eq(1)').text();
time[i]=$('table:eq(2) tr:eq('+(i+1)+') td:eq(0)').text();
};
});
if i copy the xhr.response content and i put it in the html file and i execute this js, it return me exactly what i want.
but i dont get how i can do when the html is in a variable... :'(
PS: i work on a wamp env., And a node.js env.
Since you tagged it with jQuery, why not use the built in ajax functionality:
$.ajax({
url: 'http://localhost/getsong.php',
dataType: 'html'
}).done(function(data){
//do something with the HTML
var $html = $(data),
tdtexts = $html.find('table:eq(2) tr td:first').text();
});
Is this what you're asking for?
I think, you can use innerHTML to resolve
var xhr = new XMLHttpRequest();
var parsed;
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
parsed=xhr.response;
document.getElementById('#div').innerHTML = parsed;
}
};
xhr.open("GET", 'http://localhost/getsong.php', true);
xhr.send(null);
Proceeding further after getting response may help you like,
var xhr = new XMLHttpRequest();
var parsed;
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
parsed=$.parseHTML(xhr.response);
var songs=new Array();
var time=new Array();
for (var i = 0; i < 10; i++) {
songs[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(1)').text();// use find function for parsed string
time[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(0)').text();
};
}
};
xhr.open("GET", 'http://localhost/getsong.php', true);
xhr.send(null);
By using $.ajax()
$(function(){
$.ajax({
url:'http://localhost/getsong.php',
dataType:'html',
success:function(parsed){
var songs=new Array();
var time=new Array();
for (var i = 0; i < 10; i++) {
songs[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(1)').text();// use find function for parsed string
time[i]=$(parsed).find('table:eq(2) tr:eq('+(i+1)+') td:eq(0)').text();
};
}
});
});
I think you're looking for jQuery.parseHTML(). It will parse your string into an array of DOM nodes.
http://api.jquery.com/jQuery.parseHTML/
Here's a quick example for your case:
$.get('http://relay.181.fm:8800/played.html')
.done(function(data) {
var parsed = $.parseHTML(data);
// Now parsed is an array of DOM elements which you can use selectors on, eg:
var song1 = $(parsed).find('table:eq(2) tr:eq(1) td:eq(1)').text();
console.log(song1);
});

ajax php javascript : error when using POST method

I searched on google, and there are so much question about this topic on stackoverflow. Such as 'data not being sent on post method', etc.
But seem not asnwer my question
The case is almost the same with other questions. These are the error msg:
Firefox (v21) :
InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
Chrome (v27) :
Uncaught Error: InvalidStateError: DOM Exception 11
When the request is sent by GET, there is no error. And all GET data received well.
But when sent by POST + setRequestHeader, itu occurs error like above. When setRequestHeader removed, the error is gone. No error, but the POST data is not received. i print_r($_POST); then the array is empty
Question Updated. Here is the caller:
goServer({
url : 'users/sign-in.php',
method : 'POST',
data : 'randomId=' + randomId + '&name=' + name + '&password=' + password,
done : function(response) {
alert(response);
},
fail : function(response) {
alert(response);
}
});
And here is the functions (sorry, long lines ):
function randomString() {
var str = new Date().getTime(),
str2 = Math.random();
str = str.toString();
str2 = str2.toString();
str2 = str2.substring(2,7);
str += str2;
return str;
}
function goServer(opts) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = requestComplete;
function requestComplete() {
if ( xhr.readyState === 4 ) {
if ( xhr.status === 200 ) {
opts.done(xhr.responseText);
} else {
opts.fail(xhr.responseText);
}
}
}
if ( !opts.method || opts.method === undefined ) {
opts.method = "GET";
}
if ( !opts.cache || opts.cache === undefined ) {
opts.cache = false;
}
if ( opts.cache === false ) {
opts.url += '?nocache=' + randomString();
} else {
opts.url += '?nocache=false';
}
if ( opts.method === "GET" ) {
if ( opts.data !== '' && opts.data !== undefined ) {
opts.url += '&' + opts.data;
}
opts.data = '';
} else {
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
}
xhr.open(opts.method, opts.url, true);
xhr.send(opts.data);
}
Note, the data parameter (opts.data) is set to the url when it sent by GET. When sent by POST, the paramater is set to the xhr.send(opts.data);
Question : How to get the POST data correctly?
Thank you
Call xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); after you call xhr.open
Also opts.data should be a string containing key/value pairs. e.g. key=value&method=post

XMLHttpRequest Dosen't complete

I'm calling a PHP file with XMLHttpRequest, but now the call doesn't complete and I
have no idea why. The req.readyState isn't 4, and I don't know why because the PHP file is okay and does exactly what supposed to (just echo a string).
Can anyone see what I can not see?
function processAjax(id, option) {
if (option == "lpath") url = "<?php echo $mosConfig_live_site;?>/administrator/components/com_joomlaquiz/getinfo.php?id=" + id;
else url = "<?php echo $mosConfig_live_site;?>/administrator/components/com_joomlaquiz/getinfo.php?cat=" + id;
//create AJAX request
if (window.XMLHttpRequest) { // Non-IE browsers
req = new XMLHttpRequest();
req.onreadystatechange = targetDiv();
try {
req.open("GET", url, true);
} catch (e) {
alert(e);
}
req.send(null);
} else if (window.ActiveXObject) { // IE
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = targetDiv();
req.open("GET", url, true);
req.send();
}
}
}
//this function handles the response from the ajax request
function targetDiv() {
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
//all of the code below doesn't happen because its not the option
if (option == "lpath") {
var response = req.responseText.split('##');
var articles = response[0].split(';');
var quizes = response[1].split(';');
document.getElementById("article_id").innerHTML = "";
document.getElementById("quiz_id").innerHTML = "";
for (var i = 0; i < articles.length; i = i + 2) {
if ((i + 1) <= articles.length) {
var option = new Option( /* Label */ articles[i + 1], /* Value */ articles[i]);
document.getElementById("article_id").options.add(option);
}
}
for (var i = 0; i < quizes.length; i = i + 2) {
if ((i + 1) <= quizes.length) {
var option = new Option( /* Label */ quizes[i + 1], /* Value */ quizes[i]);
document.getElementById("quiz_id").options.add(option);
}
}
delete req, articles, quizes;
} else {
document.getElementById("catdiv").innerHTML += req.responseText;
document.getElementById("allchildren").value = req.responseText;
}
} else { //failed to get response
alert("Problem: " + req.statusText);
}
}
document.getElementById("catdiv").innerHTML += "Y U NO COMPLETE?!";
}
req.onreadystatechange = targetDiv();
should be
req.onreadystatechange = targetDiv;
The original code calls targetDiv() immediately after that line of code is run, which is probably not what you wanted to do. The fixed code calls the function correctly, after the Ajax request is received.

Categories