ajax call download fails on chrome works on firefox - javascript

Hello I am using spout to run some excel reports. I have a user interface where they input date, model, and other information then I do a GET to send it to a php script where I run a query and then put all the results into an excel file like this:
ini_set('max_execution_time', 600); //300 seconds = 5 minutes
require_once 'spout-2.7.2/src/Spout/Autoloader/autoload.php'; // don't forget to change the path!
use Box\Spout\Reader\ReaderFactory;
use Box\Spout\Writer\WriterFactory;
use Box\Spout\Common\Type;
$reportDate=date("Ymd_hhmmss");
$filename="combined_report".$reportDate.".xlsx";
include ("../log/connectionToDb.php");
$conn = connectionSQL();
//provide error if connection fails
if (!$conn) {
echo "An error occurred.\n";
exit;
}
//connected successfully to db. Do not echo anything otherwise it will not show up on dropdown.
else {
//echo "connected";
}
//From date and to date static in case not provided by user
$fromDate = $_GET['convertedFrom'];
$toDate = $_GET['convertedTo'];
$line= $_GET['selectedLine'];
$model_num=$_GET['modelNumber'];
$writer = WriterFactory::create(Type::XLSX);
ob_start();
$writer->openToBrowser($filename);
$sheet = $writer->getCurrentSheet();
$sheet->setName('Production Data');
$rowCount = 2;
$flag=false;
$production = "query";
//echo memory_get_usage() ;
$result1 = sqlsrv_query($conn, $production);
if($result1 === FALSE){
die(print_r(sqlsrv_errors(), TRUE));
}
do{
if(!$flag) {
$headerRow = ['line', 'Work order','Model number', 'Revision','Serial number','Lpn','Date created','Date completed'];
$writer->addRow($headerRow);
$flag = true;
}
else{
$reportRow = [$row['line'], $row['work_order'], $row['model_num'], $row['revision'],$row['serial_num'],$row['LPN'],$row['date_created'],$row['date_completed']];
$writer->addRow($reportRow);
$rowCount++;
}
}
while ($row = sqlsrv_fetch_array($result1));
$writer->close();
$xlsData = ob_get_contents();
ob_clean();
$response = array(
'op' => 'ok',
'file' => "data:application/vnd.ms-excel;base64,".base64_encode($xlsData)
);
}
die(json_encode($response));
Then on the AJAX call I have the following:
$.ajax({
url: 'modelData/excel-export.php',
method: "GET",
data: {'modelNumber':modelNumber,'convertedFrom':converted_from_UTC,'convertedTo':converted_to_UTC,'selectedLine':selectedLine},
dataType:'json',
success: function(fileCreated){
}
}).done(function(data){
console.log(local);
var $a = $("<a>");
$a.attr("href",data.file);
$("body").append($a);
$a.attr("download","combined_report_"+local+".xlsx");
$a[0].click();
$a.remove();
});
now if I run this in Firefox everything works I am able to download up to 4 months of data which is >60,000 records this has no problem. If I run this in google chrome I cannot download more than 1 week about 20,000 records and U get a "download failed -network error" I was using PHPExcel but then found out it didn't support too many records so I switched to spout but I find the same issue only in google chrome but I don't understand where this limitation is coming from. I have read multiple posts and I have tried setting headers, lengths etc but nothing has worked also I chatted with a spout forum and they said none of the headers were necessary but they were still unable to help me.
I think this question Download failed - network error in google chrome but working in firefox may be going close to the same direction as my issue.
Also I have tried running incognito mode chrome I have tried disabling all extensions
As a side note...The firefox download appears to work fine but we don't "support" firefox so it would be hard for customers to go to multiple browsers specially when they're not tech savy
Any help will be greatly appreciated! :)

I was able to solve this issue by doing the following:
JS
window.open("modelData/excel-export.php?modelNumber="+modelNumber+"&convertedFrom="+converted_from_UTC+"&convertedTo="+converted_to_UTC+"&selectedLine="+selectedLine,
'_blank'// <- This is what makes it open in a new window.
);
then on the PHP side:
ini_set('max_execution_time', 600); //300 seconds = 5 minutes
require_once 'spout-2.7.2/src/Spout/Autoloader/autoload.php'; // don't forget to change the path!
use Box\Spout\Reader\ReaderFactory;
use Box\Spout\Writer\WriterFactory;
use Box\Spout\Common\Type;
$reportDate=date("Ymd_hhmmss");
$filename="combined_report".$reportDate.".xlsx";
include ("../log/connectionToDb.php");
$conn = connectionSQL();
//provide error if connection fails
if (!$conn) {
echo "An error occurred.\n";
exit;
}
//connected successfully to db. Do not echo anything otherwise it will not show up on dropdown.
else {
//echo "connected";
}
//From date and to date static in case not provided by user
$fromDate = $_GET['convertedFrom'];
$toDate = $_GET['convertedTo'];
$line= $_GET['selectedLine'];
$model_num=$_GET['modelNumber'];
$writer = WriterFactory::create(Type::XLSX);
$writer->openToBrowser($filename);
$sheet = $writer->getCurrentSheet();
$sheet->setName('Production Data');
$rowCount = 2;
$flag=false;
$production = "query";
//echo memory_get_usage() ;
$result1 = sqlsrv_query($conn, $production);
if($result1 === FALSE){
die(print_r(sqlsrv_errors(), TRUE));
}
do{
if(!$flag) {
$headerRow = ['line', 'Work order','Model number', 'Revision','Serial number','Lpn','Date created','Date completed'];
$writer->addRow($headerRow);
$flag = true;
}
else{
$reportRow = [$row['line'], $row['work_order'], $row['model_num'], $row['revision'],$row['serial_num'],$row['LPN'],$row['date_created'],$row['date_completed']];
$writer->addRow($reportRow);
$rowCount++;
}
}
while ($row = sqlsrv_fetch_array($result1));
$writer->close();
The library I am using just doesn't work very well with AJAX so this approach solved my issue. Thanks for all the help :)

I used Blob Javascript for the same problem.
this link maybe help someone :
Blob

Related

Upgrading my PHP chat system? (Making it only update new messages?)

JS:
"use strict";
$(document).ready(function () {
var chatInterval = 250; //refresh interval in ms
var $userName = $("#userName");
var $chatOutput = $("#chatOutput");
var $chatInput = $("#chatInput");
var $chatSend = $("#chatSend");
function sendMessage() {
var userNameString = $userName.val();
var chatInputString = $chatInput.val();
$.get("./write.php", {
username: userNameString,
text: chatInputString
});
$userName.val("");
retrieveMessages();
}
function retrieveMessages() {
$.get("./read.php", function (data) {
$chatOutput.html(data); //Paste content into chat output
});
}
$chatSend.click(function () {
sendMessage();
});
setInterval(function () {
retrieveMessages();
}, chatInterval);
});
Write.php:
<?php
require("connect.php");
//connect to db
$db = new mysqli($db_host,$db_user, $db_password, $db_name);
if ($db->connect_errno) {
//if the connection to the db failed
echo "Failed to connect to MySQL: (" . $db->connect_errno . ") " . $db->connect_error;
}
//get userinput from url
$username=substr($_GET["username"], 0, 32);
$text=substr($_GET["text"], 0, 128);
//escaping is extremely important to avoid injections!
$nameEscaped = htmlentities(mysqli_real_escape_string($db,$username)); //escape username and limit it to 32 chars
$textEscaped = htmlentities(mysqli_real_escape_string($db, $text)); //escape text and limit it to 128 chars
//create query
$query="INSERT INTO chat (username, text) VALUES ('$nameEscaped', '$textEscaped')";
//execute query
if ($db->real_query($query)) {
//If the query was successful
echo "Wrote message to db";
}else{
//If the query was NOT successful
echo "An error occured";
echo $db->errno;
}
$db->close();
?>
Read.php
<?php
require("connect.php");
//connect to db
$db = new mysqli($db_host,$db_user, $db_password, $db_name);
if ($db->connect_errno) {
//if the connection to the db failed
echo "Failed to connect to MySQL: (" . $db->connect_errno . ") " . $db->connect_error;
}
$query="SELECT * FROM chat ORDER BY id ASC";
//execute query
if ($db->real_query($query)) {
//If the query was successful
$res = $db->use_result();
while ($row = $res->fetch_assoc()) {
$username=$row["username"];
$text=$row["text"];
$time=date('G:i', strtotime($row["time"])); //outputs date as # #Hour#:#Minute#
echo "<p>$time | $username: $text</p>\n";
}
}else{
//If the query was NOT successful
echo "An error occured";
echo $db->errno;
}
$db->close();
?>
Basically everything works perfectly, except I want to allow people to copy and paste, but what the script is doing at the moment is updating every message at the chatinterval which is 250MS.
How can I make it so I can highlight a message and copy it?
So my question is, can I do this:
Can I make it only update the new messages that appear every 250-500MS instead of updating every last bit of HTML as that is a waste of resources (Especially if there was a lot of messages)
I hope you can help!
p.s. I don't want to use web sockets
To make it update just starting from the last message, get the ID of the last message, and then in your next $.get include the id of that message and get only messages that came after that.
And then use .append() in your javascript so you're not overwriting the whole thing.
It looks like you're already using jQuery. You can create a PHP script that only queries the database for entries newer than the newest one displayed, then use $.append to append the message to the <div> (or whatever other element) that holds it.
Also, as the commenter pointed out, you're still probably susceptible to SQL injection. Considering using PDO with prepared SQL statements.

Filedrop.js no success Message

i am using filedrop.js fo an Image Upload Script.
I fund a script here : https://tutorialzine.com/2011/09/html5-file-upload-jquery-php
In the Prject is a file_post.php which i wanted to change to save some informations (like the Filename) into a Database.
This is my post_file.php :
<?php
// If you want to ignore the uploaded files,
// set $demo_mode to true;
$demo_mode = false;
$upload_dir = 'uploads/tmp/';
$allowed_ext = array('jpg','jpeg','png','gif');
if(strtolower($_SERVER['REQUEST_METHOD']) != 'post'){
exit_status('Error! Wrong HTTP method!');
}
if(array_key_exists('pic',$_FILES) && $_FILES['pic']['error'] == 0 ){
$pic = $_FILES['pic'];
if(!in_array(get_extension($pic['name']),$allowed_ext)){
exit_status('Only '.implode(',',$allowed_ext).' files are allowed!');
}
if($demo_mode){
// File uploads are ignored. We only log them.
$line = implode(' ', array( date('r'), $_SERVER['REMOTE_ADDR'], $pic['size'], $pic['name']));
file_put_contents('log.txt', $line.PHP_EOL, FILE_APPEND);
exit_status('Uploads are ignored in demo mode.');
}
// Move the uploaded file from the temporary
// directory to the uploads folder:
if(move_uploaded_file($pic['tmp_name'], $upload_dir.$pic['name'])){
//My added code
include('/var/www/html/board/SSI.php');
$userName = $context['user']['name'];
$content_id = $_COOKIE["contentid"];
$pic_name = $pic['name'];
$pic_code = $content_id;
$pic_path = $pic_name;
$db_host = "******";
$db_name = "******";
$db_user = "******";
$db_pass = "******";
$db = mysqli_connect("$db_host","$db_user","$db_pass","$db_name") or die("Error " . mysqli_error($db));
$stmt = $db->prepare("INSERT INTO `User_pics` (content_id, path, user_id, user_name) VALUES (?, ?, ?, ?)");
$stmt->bind_param('ssss', $pic_code,
$pic_path,
$context['user']['id'],
$context['user']['name']);
$stmt->execute();
$stmt->close();
//end of my added code
exit_status('File was uploaded successfuly!');
}
}
exit_status('Something went wrong with your upload!');
// Helper functions
function exit_status($str){
echo json_encode(array('status'=>$str));
exit;
}
function get_extension($file_name){
$ext = explode('.', $file_name);
$ext = array_pop($ext);
return strtolower($ext);
}
?>
After i added the mysqli part the Success message is not shown anymore.
On the Image Upload the Progressbar stops at about 50%. The files are Uploaded and the informations are ssaved into the DB, but i got no success respons and this i need to handle the next steps. pleas help!
Thanks.
thanks for interrests,
two days i worked fo a soulution, after i asked here i found the Answer ;)
The Problem was the Include of the SSI.php which is encoded in UTF-8.
This was the reason for an Error in the Json encoded Response.
SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
My soulution was:
I created a cookie for User ID and User name so i was able to remove the Include. After this every thing works great. If someone has the Same Error simply create a cookie where you are showing your Upload Form, after Upload delet them.
Thanks to the Community and have a nice Day ;)

Is it possible to access the Prestashop's Web service by client (customer) login instead the key?

I'm studying Prestashop's development. And I trying to create a "third part" side application with react.js (React Native for more precision) and catch Json data in the prestashop's webservice. But I want to let the "customer" make login with his own account and only his account. With CRUD also.
in advance; Very thank you for your patience and attention.
Best Regards.
Michel Diz
Prestashop backoffice login give no access to webservices. Webservices must be enabled and a key generated. So, I recommend you that change your "login" way. Customers accounts are not related with webservices and webservices are only used to access stored data un Prestashop (more like Backoffice than Frontoffice).
What exactly do you need to do?
I hope it helps you.
I don't know if you're still searching for a solution but there is a way actually.
DO MAKE SURE IT IS A SECURE LOGIN.
Since you're giving access to all prestashop data do make sure the login is very secure. I've been able to recreate it with PHP I think that with some additions you're able to recreate it the way you want it. See it as a guideline.
To create a login system by using the prestashop webservice you'll need three things
Access through webservice to the customers table
The COOKIE_KEY, defined in app/config -> parameters.php:: 'cookie_key' => '12321test';
Some expierence with PHP
The first thing is to get the customers table from the webservice.
// code placeholder
require_once('./../PSWebServiceLibrary.php');
/**
* get information from PrestaShop
*/
$webService = new PrestaShopWebservice($url, $key, $debug);
$COOKIE_KEY = 'CookieKey';
$email = $_REQUEST['email'];
$password = $_REQUEST['password'];
$optUser = array(
'resource' => 'customers',
'filter[email]' => '[' . $email . ']',
'display' => '[id,email,lastname,firstname,passwd]'
);
$resultUser = ($webService->get($optUser));
$json = json_encode($resultUser);
The second and most important thing is to Check the user input
// code placeholder
foreach ($resultUser->customers->customer as $info) {
// Prestashop uses the cookie_key in combination with a salt key. To check the password use the php function: password_verify();
$salt = substr($info->passwd, strrpos($info->passwd, ':') + 1, 2);
$ZCpassword = md5($COOKIE_KEY . $password) . ':' . $salt;
// Check if password comparison is true or false
if (password_verify($password, $info->passwd) == true) {
session_start();
$response = array();
$response['status'] = 'succes';
$response['message'] = "You did it!";
setcookie("userId", $info->id);
header('Content-type: application/json');
echo json_encode($response);
} else {
$response = array();
$response['status'] = 'error';
$response['message'] = 'Wrong password';
header('Content-type: application/json');
echo json_encode($response);
}
}
This is how to reproduce the issue to a working example.
Hope this helps!
For those who are still searching for this answer,
<?
if (isset($_GET["email"]) && isset($_GET["password"]) )
{
$email = $_GET["email"];
$password = $_GET["password"];
$COOKIE_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
$jsonurl = "https://XXXXXXXXXXXXXXXXXXXX#example.com/api/customers?filter[email]=".$email."&display=[passwd]&output_format=JSON";
$json = file_get_contents($jsonurl);
$json_a = json_decode($json, true);
$loopone = $json_a['customers'];
$looptwo = $loopone[0];
$loopthree = $looptwo['passwd'];
$ZCpassword = md5($COOKIE_KEY . $password);
if (strcmp($loopthree, $ZCpassword) == 0) {
echo "sucess";
} else {
echo "fail";
}
}
else
{
echo "Send something with url dude";
}
?>

How to see errors about server sent events?

I coded a website using HTML5 Server Sent Events and it's working like charm on Godaddy shared hosting, however the same site with exactly the same code isn't working on 101domain shared hosting.
Rest all is working fine, except chat functionality using Server Sent Events.
How to find the errors in the script.
Here is the HTML page, with SSE javascript code.
<?php
$get_value_this_url = "globalchat";
?>
<div id="chat">
<div id="chats-div">
<p id="tip">(tip! kickstart a discussion by sharing this page)</p>
<ul id="chats-ul">
<?php
/*This session id will be used to fetch the latest chat via SSE*/
$_SESSION["id"] = 1;
if($stmt = $con->prepare("SELECT `icicinbbcts_id`, `icicinbbcts_user`, `icicinbbcts_chats` FROM `icicinbbcts_chats` WHERE `icicinbbcts_video_id` = ? ORDER BY `icicinbbcts_id` DESC LIMIT 25")){
$stmt->bind_param("s", $video_id);
$video_id = $get_value_this_url;
if ($stmt->execute()) {
$stmt->bind_result($id, $user, $chats);
$stmt->store_result();
if($stmt->num_rows() > 0){
$_SESSION["offset"] = $stmt->num_rows;
}
while ($stmt->fetch()) {
//print_r($user .": ". $chats."<br>");
echo '<li class="chats"><span id="nicknameChats">'.$user.'</span>: '.$chats.'</li>';
//echo '<span class="line-spacing"></span>';
$_SESSION["offset"] = $stmt->num_rows;
if($_SESSION["id"] < $id){
$_SESSION["id"] = $id;
}
}
}else
echo $stmt->error;
}else
echo $stmt->error;
$stmt->free_result();
$stmt->close();
?>
<script>
if(typeof(EventSource) !== "undefined") {
var source = new EventSource("auto_update.php?r=<?php echo $get_value_this_url; ?>");
source.onmessage = function(event) {
var obj = JSON.parse(event.data);
$("#chats-ul").append('<li class="chats"><span id="nicknameChats">'+obj.user+'</span>: '+obj.chats+'</li>');
$('#chats-ul').scrollTop($(window).height());
};
} else {
document.getElementById("chats-ul").innerHTML = "Your browser doesn't support a part of HTML5, so please use modern browsers like Chrome, Firefox, etc.";
}
</script>
</ul>
</div>
<input id="text-area" class="q" name="text-input" form="textForm" maxlength="140" placeholder="Type to comment" ></input>
</div>
And here's the server side PHP script.
<?php session_start(); ?>
<?php //error_reporting(E_ALL); ?>
<?php require "connection.php";?>
<?php
header('Content-Type: text/event-stream');
header('Cache-Control: no-cache');
if($stmt = $con->prepare("SELECT `icicinbbcts_id`, `icicinbbcts_user`, `icicinbbcts_chats` FROM `icicinbbcts_chats` WHERE `icicinbbcts_video_id` = ? AND `icicinbbcts_id` > ? ORDER BY `icicinbbcts_id` DESC")){
$stmt->bind_param("si", $video_id, $row_id);
$row_id = $_SESSION["id"];
$video_id = mysqli_real_escape_string($con, strip_tags($_GET["r"]));
if ($stmt->execute()) {
$stmt->bind_result($id, $user, $chats);
$stmt->store_result();
if($stmt->num_rows > 0){
while ($row = $stmt->fetch()) {
if($_SESSION["id"] < $id){
$send = array("user" => $user, "chats" => $chats);
echo "retry: 100\n";
echo "data: ".json_encode($send)."\n\n";
ob_end_flush();
flush();
$_SESSION["id"] = $id;
}
}
}
}else
echo $stmt->error;
}else
echo $stmt->error;
$stmt->close();
?>
The same above code works perfectly on Godaddy shared hosting, however the save code just isn't working on 101domain.
I tried putting charset UTF-8 in both PHP and HTML, but that din't help, I tried adding ob_flush in server side PHP script and it din't help too.
There's nothing wrong with connection.php because same file on other pages works fine.
On chat functionality the chat messages are getting inserted into the database, however it's not showing on the page, unless we refresh the page.
How to check for errors and how to debug Server Sent Events?
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
I did console.log and didn't find the log in chrome, when I placed console.log code at the point shown below in the code.
<script>
if(typeof(EventSource) !== "undefined") {
console.log("SSE is supported"); //placing console.log here, displays the message in chrome developer tool
var source = new EventSource("auto_update.php?r=<?php echo $get_value_this_url; ?>");
source.onmessage = function(event) {
console.log("message isn't received from server"); //placing console.log here doesn't display any log message in Chrome Developer Tool
var obj = JSON.parse(event.data);
$("#chats-ul").append('<li class="chats"><span id="nicknameChats">'+obj.user+'</span>: '+obj.chats+'</li>');
$('#chats-ul').scrollTop($(window).height());
};
} else {
document.getElementById("chats-ul").innerHTML = "Your browser doesn't support a part of HTML5, so please use modern browsers like Chrome, Firefox, etc.";
}
</script>
So from the console.log above, we see that the SSE script is not receiving messages from backend, and backend code is shown above, can you show what's wrong with the backend code?
Since the result it works with one provider but not another, it is probably a server configuration issue.
Here are some things you can try to narrow down the issue:
In the javascript script use console.log(event) to check if you are getting anything from the server
Check the network tab in the developer tools area of browsers (in Chrome choose other to view server sent events).
If there is no output then try narrowing the problem down on the server. Resolev SSE output early to see if SSE mechanism works. Bit by bit resolve the SSE later and later until it breaks. If there is a difference on a specific line between providers it may be due to the PHP version. To compare php versions run <?php phpinfo() ? in a php file.
If you find a difference contact your provider!
You want to report errors?
<?php
// Turn off error reporting
error_reporting(0);
// Report runtime errors
error_reporting(E_ERROR | E_WARNING | E_PARSE);
// Report all errors
error_reporting(E_ALL);
// Same as error_reporting(E_ALL);
ini_set("error_reporting", E_ALL);
// Report all errors except E_NOTICE
error_reporting(E_ALL & ~E_NOTICE);
?>

How do I insert data from a php file using PDO?

I'm trying to log some data for my website using PDO from a PHP file. I have the following code which is called by by a javascript library, D3. The call works fine, but when I run this code I get an "internal server error".
What am I doing wrong? I have been following a guide on a website and I am basically using the same principles as them. If anyone can help I'd appreciate it. Thanks a lot in advance, my code is pasted below. (Of course the database information is something valid)
$hostname="xxxx";
$username="xxxxxx";
$pw="xxxxxxxx";
$dbname="xxxx";
try {
$pdo = new PDO ("mysql:host=$hostname;dbname=$dbname","$username","$pw");
} catch (PDOException $e) {
echo "Failed to get DB handle: " . $e->getMessage() . "\n";
exit;
}
//Gets IP for client.
$ip = get_client_ip();
//An email, format of string.
$email = "test#test.dk";
//An int, in this case 19.
$prgm_name = $_GET["prgm"];
//Piece of text, format of string of course.
$prgm_options.=$prgm_name;
$prgm_options.= " - ";
$prgm_options.=$_GET["gene"];
$prgm_options.=" - ";
$prgm_options.=$_GET["data"];
//Datasize, int.
$data_size = 0;
//Timestamp.
$now = "NOW()";
//Table name.
$STAT_TABLE = "stat";
$query = $pdo->prepare("INSERT INTO $STAT_TABLE (ip, email, prgm, options, datasize, date) VALUES (:ip, :email, :prgm_name, :prgm_options, :data_size, :now);");
$query->execute(array( ':ip'=>'$ip',
':email'=>'$email',
':prgm_name'=>$prgm_name,
':prgm_options'=>'$prgm_options',
':datasize'=>'$datasize',
':now'=>$now));
Try the following Code to Insert
$count = $pdo->exec("INSERT INTO $STAT_TABLE(ip, email, prgm, options, datasize, date) VALUES ('$ip','$email',$prgm_name,'$prgm_options','$datasize',$now)))");
/*** echo the number of affected rows ***/
echo $count;
I like to bind each parameter individually. I think it gives you more control over data types and sizes.
try {
$sth = $pdo->prepare("INSERT INTO...");
$sth->bindParam(":ip", $ip, PDO::PARAM_STR, 16);
$sth->bindParam(":email", $email, PDO::PARAM_STR, 30);
// etc...
$sth->execute();
} catch (Exception $e) {
print_r($e);
}

Categories

Resources