My current project requires a file download. The file is auto generated and has an unfriendly name when it's saved, so we are changing the file name to something easier to read on download.
For example if a user downloads a file called 324343242342.pdf we change it to Lesson1.pdf or something for the one that's saved on their computer.
I'm having some trouble with ie11 with this. I know that the download attribute doesn't work on ie11, so for that sake we are using blobs and things are working fine for download purposes across browsers, but I'm not sure how to change the name of the file in ie11.
In all other browsers I just do <a href="#" :download="new_file_name"> to call a small file name calculating method in the vue component, but this doesn't work for ie11 because the "download" attribute doesn't work there.
Anyone have any idea how to go about editing that name in ie11 as well? I'm only finding answers for fixing the download functionality in general, nothing about setting a file name.
Thank you!
You have to do something similar to https://github.com/kennethjiang/js-file-download/blob/master/file-download.js
function downloadFile (data, filename, mime) {
const blob = new Blob([data], { type: mime || 'application/octet-stream' })
if (typeof window.navigator.msSaveBlob !== 'undefined') {
// For IE
window.navigator.msSaveBlob(blob, filename)
} else {
// For other browsers
const blobURL = window.URL.createObjectURL(blob)
const tempLink = document.createElement('a')
tempLink.style.display = 'none'
tempLink.href = blobURL
tempLink.setAttribute('download', filename)
if (typeof tempLink.download === 'undefined') {
tempLink.setAttribute('target', '_blank')
}
document.body.appendChild(tempLink)
tempLink.click()
document.body.removeChild(tempLink)
window.URL.revokeObjectURL(blobURL)
}
}
Related
I have a input file form field for images. When the form is submitted (via axios) the file is always corrupted.
Even when logging the file contents to the console using the FileReader Browser Api the result has encoding issues (question mark on black square).
This is the content of the original file:
This is the file content of what is being read by the browser:
It seems like this is just an encoding issue but I really don't know where the problem should be.
Here is a very basic example of the code I am using. When I submit the form data to a php endpoint or Contentful the fiel data is wrong (as in the second screenshot).
<input type='file' accept='image/*' onchange='openFile(event)'><br>
<script>
var openFile = function(event) {
var input = event.target;
var file = input.files[0];
var reader = new FileReader();
reader.onload = function () {
console.log(reader.result);
}
reader.readAsText(file);
};
</script>
I'm writing a protractor script that need to upload a JPEG image. I could click on the upload button which opens up a windows file selector. But, then I need to write the path to a file in that File Selector dialog using protractor.
But, i have no idea how it works. I tried just typing the path using sendKeys and it doesn't work so far.
Anyone have an idea how to do this?
Thanks. :)
Try my answer in "How can I control the windows File Selector using protractor".
If you need a quick solution try the following solution:
// set file detector
var remote = require('../../node_modules/protractor/node_modules/selenium-webdriver/remote');
browser.setFileDetector(new remote.FileDetector());
var fileToUpload = '../sample.txt';
var absolutePath = path.resolve(__dirname, fileToUpload);
var fileElem = element(by.css('input[type="file"]'));
// Unhide file input
browser.executeScript("arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1", fileElem.getWebElement());
fileElem.sendKeys(absolutePath);
// take a breath
browser.driver.sleep(100);
// click upload button
element(by.css('button[data-ng-click="uploadFile(file)"]')).click(); // does post request
[settingsEditProfile_page.settingsEditProfile_UploadImageButton()][1].isDisplayed().then(function () {
helperUtil.addStep("User redirected to Edit Profile page"); settingsEditProfile_page.settingsEditProfile_UploadImageButton().sendKeys(absolutePath).then(function () {
helperUtil.addStep("User clicked on upload button and uploaded new image");
browser.driver.sleep(3000);
settingsEditProfile_page.settingsEditProfile_Save().click().then(function () {
helperUtil.addStep("User clicked on SAVE button");
});
});
});
uploadFile: async (locator, filepath) => {
absolutePath = path.resolve(filepath);
click(locator);
element(by.css('input[type="file"]')).sendKeys(absolutePath);
await sleep(10000, "wait to close window");
await closePopup();
},
I am using Appcelerator Titanium 3.0.2 to allows user to watch/download videos&audios. Here is part of code to get the file object and play the audio.
var filename = self.url.substring(self.url.lastIndexOf('/')+1);
var file = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory,filename);
if(!file.exists())
self._download(self.url, filename, Ti.Filesystem.tempDirectory, function(){
setAudUrl(file.nativePath);
timeBar.max = audPlayer.duration*1000;
prgHandle = setInterval(updateProgressBar,10000);
audPlayer.play();
audCtrlBar.show();
loading.hide();
},
function(_progress,_position){
httpClient=_position;
loading.show();
},
function(){
noLabel.show();
loading.hide();
});
else {
setAudUrl(file.nativePath);
timeBar.max = audPlayer.duration*1000;
prgHandle = setInterval(updateProgressBar,10000);
audPlayer.play();
audCtrlBar.show();
}
This code is working, but my question is how to remove the file when the user exist the app. Since Apple required that file in /tmp directory will be removed after user exist the app. Anyone can help? Thanks.
You could use Titanium's application events pause and paused. They are called when the app becomes inactive but this only works on iOS.
Titanium.App.addEventListener('pause' /* or paused, see docs */, function() {
var dir = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory, 'tmpDownloads'); // ensure that you use the same folder for storing the downloaded files. A separate folder is easier to remove.
if(dir.exists() && dir.isDirectory()) {
dir.deleteDirectory(true); // true removes recursively the directory and its contents
}
});
You need to create the directory again when resume-ing the app.
I see that CasperJS has a "download" function and an "on resource received" callback but I do not see the contents of a resource in the callback, and I don't want to download the resource to the filesystem.
I want to grab the contents of the resource so that I can do something with it in my script. Is this possible with CasperJS or PhantomJS?
This problem has been in my way for the last couple of days. The proxy solution wasn't very clean in my environment so I found out where phantomjs's QTNetworking core put the resources when it caches them.
Long story short, here is my gist. You need the cache.js and mimetype.js files:
https://gist.github.com/bshamric/4717583
//for this to work, you have to call phantomjs with the cache enabled:
//usage: phantomjs --disk-cache=true test.js
var page = require('webpage').create();
var fs = require('fs');
var cache = require('./cache');
var mimetype = require('./mimetype');
//this is the path that QTNetwork classes uses for caching files for it's http client
//the path should be the one that has 16 folders labeled 0,1,2,3,...,F
cache.cachePath = '/Users/brandon/Library/Caches/Ofi Labs/PhantomJS/data7/';
var url = 'http://google.com';
page.viewportSize = { width: 1300, height: 768 };
//when the resource is received, go ahead and include a reference to it in the cache object
page.onResourceReceived = function(response) {
//I only cache images, but you can change this
if(response.contentType.indexOf('image') >= 0)
{
cache.includeResource(response);
}
};
//when the page is done loading, go through each cachedResource and do something with it,
//I'm just saving them to a file
page.onLoadFinished = function(status) {
for(index in cache.cachedResources) {
var file = cache.cachedResources[index].cacheFileNoPath;
var ext = mimetype.ext[cache.cachedResources[index].mimetype];
var finalFile = file.replace("."+cache.cacheExtension,"."+ext);
fs.write('saved/'+finalFile,cache.cachedResources[index].getContents(),'b');
}
};
page.open(url, function () {
page.render('saved/google.pdf');
phantom.exit();
});
Then when you call phantomjs, just make sure the cache is enabled:
phantomjs --disk-cache=true test.js
Some notes:
I wrote this for the purpose of getting the images on a page without using the proxy or taking a low res snapshot. QT uses compression on certain text file resources and you will have to deal with the decompression if you use this for text files. Also, I ran a quick test to pull in html resources and it didn't parse the http headers out of the result. But, this is useful to me, hopefully someone else will find it so, modify it if you have problems with a specific content type.
I've found that until the phantomjs matures a bit, according to the issue 158 http://code.google.com/p/phantomjs/issues/detail?id=158 this is a bit of a headache for them.
So you want to do it anyways? I've opted to go a bit higher to accomplish this and have grabbed PyMiProxy over at https://github.com/allfro/pymiproxy, downloaded, installed, set it up, took their example code and made this in proxy.py
from miproxy.proxy import RequestInterceptorPlugin, ResponseInterceptorPlugin, AsyncMitmProxy
from mimetools import Message
from StringIO import StringIO
class DebugInterceptor(RequestInterceptorPlugin, ResponseInterceptorPlugin):
def do_request(self, data):
data = data.replace('Accept-Encoding: gzip\r\n', 'Accept-Encoding:\r\n', 1);
return data
def do_response(self, data):
#print '<< %s' % repr(data[:100])
request_line, headers_alone = data.split('\r\n', 1)
headers = Message(StringIO(headers_alone))
print "Content type: %s" %(headers['content-type'])
if headers['content-type'] == 'text/x-comma-separated-values':
f = open('data.csv', 'w')
f.write(data)
print ''
return data
if __name__ == '__main__':
proxy = AsyncMitmProxy()
proxy.register_interceptor(DebugInterceptor)
try:
proxy.serve_forever()
except KeyboardInterrupt:
proxy.server_close()
Then I fire it up
python proxy.py
Next I execute phantomjs with the proxy specified...
phantomjs --ignore-ssl-errors=yes --cookies-file=cookies.txt --proxy=127.0.0.1:8080 --web-security=no myfile.js
You may want to turn your security on or such, it was needless for me currently as I'm scraping just one source. You should now see a bunch of text flowing through your proxy console and if it lands on something with the mime type of "text/x-comma-separated-values" it'll save it as data.csv. This will also save all the headers and everything, but if you've come this far I'm sure you can figure out how to pop those off.
One other detail, I've found that I've had to disable gzip encoding, I could use zlib and decompress data in gzip from my own apache webserver, but if it comes out of IIS or such the decompression will get errors and I'm not sure about that part of it.
So my power company won't offer me an API? Fine! We do it the hard way!
Did not realize I could grab the source from the document object like this:
casper.start(url, function() {
var js = this.evaluate(function() {
return document;
});
this.echo(js.all[0].outerHTML);
});
More info here.
You can use Casper.debugHTML() to print out contents of a HTML resource:
var casper = require('casper').create();
casper.start('http://google.com/', function() {
this.debugHTML();
});
casper.run();
You can also store the HTML contents in a var using casper.getPageContent(): http://casperjs.org/api.html#casper.getPageContent (available in lastest master)
I am using a dojox.form.uploader.FileList here: https://github.com/chotchki/pgGallery/blob/master/src/main/webapp/WEB-INF/views/gallery/gallery.jsp#L129
I have looked through the API documentation and can't find a way to allow the user to remove a file from the list to be uploaded before they click upload.
Any ideas?
I found no solution too, so i wrote this little hack, it just extending dojox/form/Uploader. So far it seems to work for me, at least in Firefox. It adds a method removeFile(index) and a onRemove(file) method to the Uploader class.
What you need to do is use force="iframe" on your uploader Element or set the property on your object.
require(["dojo/_base/lang","dojox/form/Uploader","dojo/dom-construct","dojo/_base/array"],function(lang, Uploader, domConstruct, array){
lang.extend(Uploader,{
removeFile: function(index){
if(this._inputs.length > index){
//Delete input field from dom
domConstruct.destroy(this._inputs[index]);
//Delete file From input Array
var _arr = new Array();
var _file = this._inputs[index];
array.forEach(this._inputs,function(n,i){
if(i != index){
_arr.push(n);
}
});
this._inputs = _arr;
this.onRemove(_file);
}
},
onRemove: function(file){
}
});
});