I am trying to create a zip file using jsZip . The contents of the zip file are images from the web.
I have created the following code. But when i run it all am getting is an empty zip file of 22kb.
<html>
<body>
<script type="text/javascript" src="jszip.js"></script>
<script type="text/javascript" src="FileSaver.js"></script>
<script type="text/javascript" src="jszip-utils.min.js"></script>
<script>
var imgLinks = ["url1", "url2", "url3"];
function create_zip() {
var zip = new JSZip();
for (var i = 0; i < imgLinks.length; i++) {
JSZipUtils.getBinaryContent(imgLinks[i], function(err, data) {
if (err) {
alert("Problem happened when download img: " + imgLink[i]);
console.erro("Problem happened when download img: " + imgLink[i]);
deferred.resolve(zip); // ignore this error: just logging
// deferred.reject(zip); // or we may fail the download
} else {
zip.file("picture" + i + ".jpg", data, {
binary: true
});
deferred.resolve(zip);
}
});
}
var content = zip.generate({
type: "blob"
});
saveAs(content, "downloadImages.zip");
}
</script>
<br/>
<br/>
<center>
Click the button to generate a ZIP file
<br/>
<input id="button" type="button" onclick="create_zip()" value="Create Zip" />
</center>
</body>
</html>
(url1 , url2 and url3 replaced by image urls i want to download).
Why am i getting these empty zip files?
JSZipUtils.getBinaryContent is asynchronous : the content will be added after the call to zip.generate(). You should wait for all images before generating the zip file.
Edit :
If the files you are loading are on a different server, this server need to send additional HTTP headers, like Access-Control-Allow-Origin: server-hosting-the-page.com. The Firefox or Chrome debug console will show an error in that case. The js library can't detect a CORS issue (see here) and will trigger a success with an empty content.
Related
I am trying to print a pdf with PDF.js but currently I cannot get the document data rendered in the pdf element. This is what it looks like right now:
So, no data is being rendered.
This is the code behind:
<script src="jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="pdf.js"></script>
<script type="text/javascript" src="pdf.worker.js"></script>
<body id="printbody" style="margin:0px;">
</body>
<script type="text/javascript">
var pdfData = atob('JVBERi0xLjQK...'); //Shortened
PDFJS.workerSrc = 'pdf.worker.js';
PDFJS.getDocument({data: pdfData}).then(function RenderAndPrint(res) {
var src = URL.createObjectURL(new Blob([res], { type: 'application/pdf' }))
var printFrame = document.createElement('iframe');
printFrame.id = 'print-frame';
//printFrame.style.display = 'none';
printFrame.style.width = '100%'
printFrame.style.height = '100%'
printFrame.style.border = 'none'
printFrame.src = src;
document.body.appendChild(printFrame);
setTimeout(function () {
printFrame.contentWindow.print();
}, 0)
});
</script>
The final goal is to have this entire page appended to an existing page via AJAX so the as soon as the this page is appended and renders the PDF, the iframe (which would be hidden) would print the pdf as soon as it renders and then eventually dispose of itself.
I was using itextsharp, I instead saved the pdf to the local system, set it to print on open like so:
PdfAction print = new PdfAction(PdfAction.PRINTDIALOG);
writer.SetOpenAction(print);
and then used an iframe to render the pdf by setting the file to the src
I'm having issues with developing my Google Chrome extension. I need some specific npm modules in order to execute my code so I looked into Browserify. I followed all the steps without issue but the code still produces errors when run. The screenshot is attached below.
Error when Chrome extension is only loaded
All my files are located in the same project folder (popup.html, popup.js, bundle.js, etc.). I only have one html file and one javascript file (excluding bundle.js).
Here is my popup.html code:
document.addEventListener('DOMContentLoaded', function() {
var convertMP3Button = document.getElementById("getLinkAndConvert");
convertMP3Button.addEventListener("click", function() {
chrome.tabs.getSelected(null, function(tab) { // 'tab' has all the info
var fs = require('fs');
var ytdl = require('ytdl-core');
var ffmpeg = require('fluent-ffmpeg');
var ffmetadata = require("ffmetadata");
var request = require('request');
console.log(tab.url); //returns the url
convertMP3Button.textContent = tab.url;
var url = tab.url;
var stream = ytdl(url);
//.pipe(fs.createWriteStream('/Users/nishanth/Downloads/video.mp4'));
// Helper method for downloading
var download = function(uri, filename, callback){
request.head(uri, function(err, res, body){
request(uri).pipe(fs.createWriteStream(filename)).on('close', callback);
});
};
ytdl.getInfo(url, function(err, info) {
console.log("INFO: " + JSON.stringify(info, null, 2));
var process = new ffmpeg({source:stream})
process.save('/Users/nishanth/Downloads/' + info.title + '.mp3').on('end', function() {
console.log("PROCESSING FINISHED!");
download(info.thumbnail_url, "/Users/nishanth/Downloads/image.jpg", function() {
console.log("DOWNLOADED IMAGE");
var options = {
artist: info.author,
attachments: ["/Users/nishanth/Downloads/image.jpg"]
};
ffmetadata.write('/Users/nishanth/Downloads/' + info.title + '.mp3', {}, options, function(err) {
if (err)
console.error("Error writing cover art: " + err);
else
console.log("Cover art added");
});
});
});
});
});
});
});
<!doctype html>
<html>
<head>
<title>Youtube Music</title>
<script src="bundle.js"></script>
<script src="popup.js"></script>
</head>
<body>
<h1>Youtube Music</h1>
<button id="getLinkAndConvert">Download Song Now!</button>
</body>
</html>
It would be great if I could find out the reason why I have not been able to properly integrate browserify in order to use the npm modules.
Browsers don't allow you to access the file system, instead they usually have some storage mechanisms of their own (cookies, localstorage, or a browser-specific system like chrome.storage). Browserify has no way of getting around this, and doesn't provide a shim for require('fs'). Instead of writing directly to disk you'll need to have your app provide a downloadable version of your files, which the user will then have to save manually. If you don't need the files to be accessible outside the extension you can use the api I linked earlier, or drop in something like browserify-fs which creates a virtual file system in the browser's storage.
I just found a working docx to html converter using only javascript on github. The main code which converts docx to html is below. The issue is the page just has a button which on click or drag and choosing a word document, opens it as html. I want to specify a file location in the code so I can load it on the server for loading some documents from computer locally.
Code which converts docx to html and renders :
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DocxJS Example</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script type="text/javascript" src="https://www.docxjs.com/js/build/latest.docxjs.min.js"></script>
</head>
<body>
<input id="inputFiles" type="file" name="files[]" multiple="false">
<div id="loaded-layout" style="width:100%;height:800px;"></div>
<script>
$(document).ready(function(){
var $inputFiles = $('#inputFiles');
$inputFiles.on('change', function (e) {
var files = e.target.files;
var docxJS = new DocxJS();
docxJS.parse(
files[0],
function () {
docxJS.render($('#loaded-layout')[0], function (result) {
if (result.isError) {
console.log(result.msg);
} else {
console.log("Success Render");
}
});
}, function (e) {
console.log("Error!", e);
}
);
});
});
</script>
</body>
</html>
I tried changing var files = e.target.files; to var files = "C:/sda/path/to/docx"; but that didn't help.
I tried to change
var files = e.target.files;
to
var files = new Array(new File([""], "sample.docx"));
but it gives me OOXML parse error.
Update:
Lets say I have a file location variable in PHP and I wish to use that instead in the javascript code. How do I do it?
I also checked docx2html javascript code and here is the code for it:
<!DOCTYPE html>
<html>
<head>
<script src="index.js"></script>
<script>
function test(input){
require("docx2html")(input.files[0]).then(function(converted){
text.value=converted.toString()
})
}
</script>
</head>
<body>
<input type="file" style="position:absolute;top:0" onchange="test(this)">
<br/>
<br/>
<textarea id="text"></textarea>
</body>
</html>
Same issue need input.files[0] here as well
Update:
I am trying to use the method mentioned in the comments but encounter some errors:
var fil;
var getFileBlob = function (url, cb) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "blob";
xhr.addEventListener('load', function() {
cb(xhr.response);
});
xhr.send();
};
var blobToFile = function (blob, name) {
blob.lastModifiedDate = new Date();
blob.name = name;
return blob;
};
var getFileObject = function(filePathOrUrl, cb) {
getFileBlob(filePathOrUrl, function (blob) {
cb(blobToFile(blob, 'test.docx'));
});
};
getFileObject('demo.docx', function (fileObject) {
console.log(fileObject);
fil = fileObject;
});
The error primarily was “Cross origin requests are only supported for HTTP.” before I used https://calibre-ebook.com/downloads/demos/demo.docx instead of just demo.docx in above file path. This however gives another error:
Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https, chrome-extension-resource.
which means chrome cannot load it. It needs to be working on a server. If someone can help providing a fix to make it work offline, let me know. The last method was asynchronous call.
In the browser, there is a sandbox policy.
It can not access files directly via Path.
Please access the file through drag & drop event or input file change event.
I have been following This tutorial on using the JQuery file upload plugin. everything looks fine and when I select a file to upload the browser there are no errors but the file doesn't seem to upload. I could be wrong but I assumed the file would be in the uploads folder in the project directory(eclipse). Here is the code:
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Mini Ajax File Upload Form</title>
<!-- Google web fonts -->
<link href="http://fonts.googleapis.com/css?family=PT+Sans+Narrow:400,700" rel='stylesheet' />
<!-- The main CSS file -->
<link href="assets/css/style.css" rel="stylesheet" />
</head>
<body>
<form id="upload" method="post" action="upload.php" enctype="multipart/form-data">
<div id="drop">
Drop Here
<a>Browse</a>
<input type="file" name="upl" multiple />
</div>
<ul>
<!-- The file uploads will be shown here -->
</ul>
</form>
<!-- JavaScript Includes -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="assets/js/jquery.knob.js"></script>
<!-- jQuery File Upload Dependencies -->
<script src="assets/js/jquery.ui.widget.js"></script>
<script src="assets/js/jquery.iframe-transport.js"></script>
<script src="assets/js/jquery.fileupload.js"></script>
<!-- Our main JS file -->
<script src="assets/js/script.js"></script>
</body>
</html>
script.js
$(function(){
var ul = $('#upload ul');
$('#drop a').click(function(){
// Simulate a click on the file input button
// to show the file browser dialog
$(this).parent().find('input').click();
});
// Initialize the jQuery File Upload plugin
$('#upload').fileupload({
// This element will accept file drag/drop uploading
dropZone: $('#drop'),
// This function is called when a file is added to the queue;
// either via the browse button, or via drag/drop:
add: function (e, data) {
var tpl = $('<li class="working"><input type="text" value="0" data-width="48" data-height="48"'+
' data-fgColor="#0788a5" data-readOnly="1" data-bgColor="#3e4043" /><p></p><span></span></li>');
// Append the file name and file size
tpl.find('p').text(data.files[0].name)
.append('<i>' + formatFileSize(data.files[0].size) + '</i>');
// Add the HTML to the UL element
data.context = tpl.appendTo(ul);
// Initialize the knob plugin
tpl.find('input').knob();
// Listen for clicks on the cancel icon
tpl.find('span').click(function(){
if(tpl.hasClass('working')){
jqXHR.abort();
}
tpl.fadeOut(function(){
tpl.remove();
});
});
// Automatically upload the file once it is added to the queue
var jqXHR = data.submit();
},
progress: function(e, data){
// Calculate the completion percentage of the upload
var progress = parseInt(data.loaded / data.total * 100, 10);
// Update the hidden input field and trigger a change
// so that the jQuery knob plugin knows to update the dial
data.context.find('input').val(progress).change();
if(progress == 100){
data.context.removeClass('working');
}
},
fail:function(e, data){
// Something has gone wrong!
data.context.addClass('error');
}
});
// Prevent the default action when a file is dropped on the window
$(document).on('drop dragover', function (e) {
e.preventDefault();
});
// Helper function that formats the file sizes
function formatFileSize(bytes) {
if (typeof bytes !== 'number') {
return '';
}
if (bytes >= 1000000000) {
return (bytes / 1000000000).toFixed(2) + ' GB';
}
if (bytes >= 1000000) {
return (bytes / 1000000).toFixed(2) + ' MB';
}
return (bytes / 1000).toFixed(2) + ' KB';
}
});
upload.php
<?php
// A list of permitted file extensions
$allowed = array('png', 'jpg', 'gif','zip');
if(isset($_FILES['upl']) && $_FILES['upl']['error'] == 0){
$extension = pathinfo($_FILES['upl']['name'], PATHINFO_EXTENSION);
if(!in_array(strtolower($extension), $allowed)){
echo '{"status":"error"}';
exit;
}
if(move_uploaded_file($_FILES['upl']['tmp_name'], 'uploads/'.$_FILES['upl']['name'])){
echo '{"status":"success"}';
exit;
}
}
echo '{"status":"error"}';
exit;
All the other required js files are also present. When i run it on tomcat, my output looks like this:
I refreshed the project as well so that's not it. Any help would be great, thanks.
You are not running PHP on the server so the upload isn't saved anywhere.
You need to install PHP on the server, move to a server that has PHP installed or change to another language.
It looks like you're using Windows. You could try using WAMP-server.
In a prior post I was trying to upload a file to a server using HTML and Javascript. I ran into several problems with my implementation so I've taken a different approach. I have a HTML form and a python script in the cgi directory of my webserver. Here is my HTML code...
<html>
<head>
<script type="text/javascript">
function loadXMLDoc(){
var xmlhttp;
if (window.XMLHttpRequest){
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else{
// code for IE6, IE5 seriously, why do I bother?
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
document.getElementById("outputDiv").innerHTML=xmlhttp.responseText;
}
}
var file = document.getElementById('idexample').value;
xmlhttp.open("GET","/cgi/ajax.py?uploadFile="+file,true);
xmlhttp.send();
}
</script>
</head>
<body onload="changeInput()">
<form name = "form_input" enctype="multipart/form-data" method="POST">
<input type="file" ACCEPT="text/html" name="uploadFile" id="idexample" />
<button type="button" onclick="loadXMLDoc()">Enter</button>
</form>
<div id="outputDiv"></div>
</body>
</html>
I am using AJAX because it occured to me that my cgi script could take up to a couple of minutes to run depending on the file the user enters. What I'm trying to do is get the contents of the file passed to my python CGI script and print them out on the page. All I'm getting is "C:\fakepath\. What I want to do is get the file contents. Here is my cgi script...
#!/usr/bin/python
import cgi
form = cgi.FieldStorage()
print 'Content-Type: text/html\n'
if form.has_key('uploadFile'):
print str(form['uploadFile'].value)
else:
print 'no file'
Also should I be using
xmlhttp.open("POST","/cgi/ajax.py",true);
instead of
xmlhttp.open("GET","/cgi/ajax.py?uploadFile="+file,true);
I tried both but the POST one doesn't even return the name of my file. Also it occured to me that I read that I may not even need the tags in my script since I submit this information using javascript. Is this true. My page seems to work without the form tags (at least on Chrome and Firefox).
If you examine the variable file using console.log(), you will notice that it only contains the filename and not its contents.
var file = document.getElementById('idexample').value;
console.log(file); // Outputs filename
The standard way to upload a file via AJAX is to use an iframe. The following code is taken from jquery.extras.js and is based on malsup's form plugin.
<html>
<body>
<form id=input action=/cgi/ajax.py method=post>
<input type=file name=uploadFile>
<input type=submit value=Submit>
</form>
<div id=output></div>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js'></script>
<script>
$.fn.ajaxForm = function(options) {
options = $.extend({}, {
onSubmit:function() {},
onResponse:function(data) {}
}, options);
var iframeName = 'ajaxForm', $iframe = $('[name=' + iframeName + ']');
if (!$iframe.length) {
$iframe = $('<iframe name=' + iframeName + ' style="display:none">').appendTo('body');
}
return $(this).each(function() {
var $form = $(this);
$form
.prop('target', iframeName)
.prop('enctype', 'multipart/form-data')
.prop('encoding', 'multipart/form-data')
.submit(function(e) {
options.onSubmit.apply($form[0]);
$iframe.one('load', function() {
var iframeText = $iframe.contents().find('body').text();
options.onResponse.apply($form[0], [iframeText]);
});
});
});
};
$('#input').ajaxForm({
onResponse:function(data) {
$('#output').html(data);
}
});
</script>
</body>
</html>
Your CGI code is fine. However, I highly recommend using a web framework like Pyramid or Django for your own sanity.
#!/usr/bin/python
import cgi
form = cgi.FieldStorage()
print 'Content-Type: text/html\n'
if 'uploadFile' in form and form['uploadFile'].filename:
print form['uploadFile'].value
else:
print 'no file'