I'm currently developing an application where the user clicks on an element, that element calls a JS function and the function handles a file download.
The files are reports generated dynamically by Devexpress XtraReports module, converted to Base64 and then sent back to the client side. When the client receives the Base64 string, the JS function creates an <a> element, sets the href attribute to data:application/pdf;base64,JVBERi0xLjQNCiWio[...] and simulates a click with the click() event.
Here's the piece of JS code that handles the file download:
let downloadLink;
try {
downloadLink = executionId ? await getLinkPdfBase64(executionId) : false;
} catch (error) {
downloadLink = false;
console.log(error);
}
if (downloadLink) {
const aElement = document.createElement("a");
downloadLink = "data:application/pdf;base64," + downloadLink;
aElement.setAttribute("download", currentReportData.LayoutName);
aElement.setAttribute("href", downloadLink);
aElement.click();
aElement.remove();
} else {
DevExpress.ui.dialog.alert( //Ignore this, it's a Devexpress component
"Your report could not be generated",
"Alert"
);
}
The problem is:
When I generate a report with custom parameter types, Devexpress generates it correctly (the Base64, if converted to string, is visibly correctly formed) but the browser (Google Chrome) downloads the file with the extension ".0".
If the report has normal Devexpress parameters (like Strings, Int32, Guids, etc)) the file is downloaded with the correct ".pdf" extension.
Here's a picture of a correctly downloaded PDF and a ".0" extension file:
Could it be the JS function the cause or the solution to the problem? If not, almost for sure there will be something wrong with the report generator (Devexpress).
NB: If I manually change the ".0" extension to ".pdf" the file opens and it is displayed / formed correctly.
Turns out I ended up solving it just by adding the file extension ".pdf" in the download attribute, so when the browser can't recognize it, you are already specifying which one it is:
aElement.setAttribute("download", currentReportData.LayoutName + ".pdf");
Given https://www.example.com/image-list:
...
<a href="/image/1337">
<img src="//static.example.com/thumbnails/86fb269d190d2c85f6e0468ceca42a20.png"/>
</a>
<a href="//static.example.com/full/86fb269d190d2c85f6e0468ceca42a20.png"
download="1337 - Hello world!.png">
Download
</a>
...
This is a user script environment, so I have no access to server configuration. As such:
I can't make server accept user-friendly file names like https://static.example.com/full/86fb269d190d2c85f6e0468ceca42a20 - 1337 - Hello World!.png.
I can't configure Cross-Origin Resource Sharing. www.example.com and static.example.com are separated by CORS wall by design.
How to make Firefox and Chrome display Save File As dialog with the suggested file name "1337 - Hello world!.png" when a user clicks on the "Download" link?
After some failing and googling, I learned these problems:
Firefox completely ignores existence of the download attribute on some image MIME types.
Firefox completely ignores existence of the download attribute on cross-site links.
Chrome completely ignores value of the download attribute on cross-site links.
All these points don't make any sense to me, all look like "let's put random non-sensical limitations on the feature", but I have to accept them as it's my environment.
Do any ways to solve the problem exist?
Background: I'm writing a user script for an image board which uses MD5 hashes as file names. I want to make saving with user-friendly names easier. Anything which gets me closer to this would be helpful.
I guess I can get around the limitations by using object URLs to blobs and a local proxy with hacked CORS headers, but this setup is obviously beyond reasonable. Saving through canvas could work (are images "protected" by CORS in this case too?), but it will either force double lossy compression or lossy-to-lossless conversion, given JPEG files, neither of which are good.
All modern browsers will ignore the download attribute in the anchor tag for cross-origin URL'S.
Reference : https://html.spec.whatwg.org/multipage/links.html#downloading-resources
According to the spec makers, this represents a security loophole as a user could be tricked into downloading malicious files while browsing a secure site, believing that the file is also originating from the same secure site.
Any interesting conversation for implementing this feature in the firefox browser can be found here : https://bugzilla.mozilla.org/show_bug.cgi?id=676619
[ Edit by Athari ]
Quote from specification:
This could be dangerous, because, for instance, a hostile server could be trying to get a user to unknowingly download private information and then re-upload it to the hostile server, by tricking the user into thinking the data is from the hostile server.
Thus, it is in the user's interests that the user be somehow notified that the resource in question comes from quite a different source, and to prevent confusion, any suggested filename from the potentially hostile interface origin should be ignored.
Clarification on the mysterious scenario:
the more serious issue with CORS downloads is if a malicious site forces a download of a file form a legitimate site and some how gets access to its content. so lets say I download the user gmail inbox page and explore its messages.
in this case an evil site will have to fool the user into downloading the file and uploading it back to the server, so lets say we have a gmail.com/inbox.html actually contains all the user mail messages and the attacker sites offers a download link for a coupon file, that should be uploaded to another evil site. the coupon will supposedly offer a 30% discount on a new Ipad. the download link will actually point to gmail.com/inbox.html and will download it as "30off.coupon", the if the user will download this file and upload it without checking it's content the evil site will get the user "coupon" and so its inbox content.
Important notes:
Google originally didn't limit download attribute by CORS and was explicitly against this. It was later forced to adjust Chrome implementation.
Google was opposed to using CORS for this.
Alternative solutions were proposed with giving a user a warning about cross-origin downloads. They were ignored.
Well there can be notification or deny/allow mechanism when downloading from another origin (e.g. like in case of geolocation API). Or not to send cookies in case of cross origin request with download attribute.
Some developers do share the opinion that the restriction is too strong, severely limits the usage of the feature and that the scenario is so complicated that the user who would do this would easily download and run an executable file. Their opinion was disregarded.
The case against allowing cross-origin downloads is centered around the premise that visitors of an [evil] site (eg, discountipads.com) could unknowingly download a file from a site containing their own personal information (eg, gmail.com) and save it to their disk using a misleading name (eg, "discount.coupon") AND THEN proceed to another malicious page where they manually upload that same file they just downloaded. This is quite far-fetched in my opinion, and anyone who would succumb to such trivial trickery perhaps does not belong online in the first place. I mean c'mon...Click here to download our special discount offer and then re-upload it through our special form! Seriously? Download our special offer and then email it to this Yahoo address for a big discount! Do the people who fall for these things even know how to do email attachments?
I'm all for browser security, but if the good people of Chromium have no problem with this I don't see why Firefox has to completely banish it. At the very least I'd like to see a preference in about:config to enable cross-origin #download for "advanced" users (default it to false). Even better would be a confirmation box similar to: "Although this page is encrypted, the information you submit through this form won't be" or: "This page is requesting to install addons" or: "Files downloaded from the web may harm your computer" or even: "The security certificate of this page is invalid" ...y'know what I mean? There are myriad ways to heighten the user's awareness and inform them this might not be safe. One extra click and a short (or long?) delay is enough to let them assess the risk.
As the web grows, and the use of CDNs grows, and the presence of advanced web-apps grows, and the need to manage files hosted across servers grows, features like #download will become more important. And when a browser like Chrome supports it fully whereas Firefox does not, this is not a win for Firefox.
In short, I think that mitigating the potential evil uses of #download by simply ignoring the attribute in cross-origin scenarios is a woefully ill-thought move. I'm not saying the risk is entirely non-existent, quite the contrary: I am saying there are plenty of risky things one does online in the course of his day...downloading ANY file is high among them. Why not work around that issue with a well-thought user experience?
Overall, considering widespread use of CDNs and intentionally putting user-generated content on a different domain, the primary use for the download attribute is specifying a file name for blob downloads (URL.createObjectURL) and the like. It can't be used in a lot of configurations and certainly not very useful in user scripts.
Try something like:
Get the external image to your server first
Return the fetched image from your server.
Dynamically create an anchor with download name and .click() it!
while the above was just a pretty short tips list... give this a try:
on www.example.com place a fetch-image.php with this content:
<?php
$url = $_GET["url"]; // the image URL
$info = getimagesize($url); // get image data
header("Content-type: ". $info['mime']); // act as image with right MIME type
readfile($url); // read binary image data
die();
or with any other server-side language that achieves the same.
The above should return any external image as it's sitting on your domain.
On your image-list page, what you can try now is:
<a
href="//static.example.com/thumbnails/86fb269d190d2c85f6e0468ceca42a20.png"
download="1337 - Hello world!.png">DOWNLOAD</a>
and this JS:
function fetchImageAndDownload (e) {
e.preventDefault(); // Prevent browser's default download stuff...
const url = this.getAttribute("href"); // Anchor href
const downloadName = this.download; // Anchor download name
const img = document.createElement("img"); // Create in-memory image
img.addEventListener("load", () => {
const a = document.createElement("a"); // Create in-memory anchor
a.href = img.src; // href toward your server-image
a.download = downloadName; // :)
a.click(); // Trigger click (download)
});
img.src = 'fetch-image.php?url='+ url; // Request image from your server
}
[...document.querySelectorAll("[download]")].forEach( el =>
el.addEventListener("click", fetchImageAndDownload)
);
You should see finally the image downloaded as
1337 - Hello world!.png
instead of 86fb269d190d2c85f6e0468ceca42a20.png like it was the case.
Notice: I'm not sure about the implications of simultaneous requests toward fetch-image.php - make sure to test, test.
If you have access to both, backend and frontend code, here are steps which could help you
I'm not sure which type of backend language you are using, so I will just explain what need to be done without code sample.
In backend, for preview your code should work as is, if you get in query string something like ?download=true then your backend should pack file as dispositioned content, in other words you would use content-disposition response header. This will open you possibility to put additional attributes to content, like filename, so it could be simething like this
Content-Disposition: attachment; filename="filename.jpg"
Now, in frontent, any link which should behave as download button need to contain ?download=true in href query parameter AND target="_blank" which will temporary open another tab in browser for download purpose.
<a href="/image/1337">
<img src="//static.example.com/thumbnails/86fb269d190d2c85f6e0468ceca42a20.png"/>
</a>
<a href="//static.example.com/full/86fb269d190d2c85f6e0468ceca42a20.png?download=true" target="_blank" title="1337 - Hello world!.png">
Download Full size
</a>
I know that this works without CORS setup and if user clicks on download link, but I never tested Save As dialog in browser... and it will take some time to build this again, so please give it a try.
Relevant Chromium API...
https://developer.chrome.com/extensions/downloads#event-onDeterminingFilename
Example...
chrome.downloads.onDeterminingFilename.addListener(function(item,suggest){
suggest({filename:"downloads/"+item.filename}); // suggest only the folder
suggest({filename:"downloads/image23.png"}); // suggest folder and filename
});
Oops... you're on server side but I assumed client side! I'll leave this here though in case someone needs it.
You can try to do this
var downloadHandler = function(){
var url = this.dataset.url;
var name = this.dataset.name;
// by this you can automaticaly convert any supportable image type to other, it is destination image format
var mime = this.dataset.type || 'image/jpg';
var image = new Image();
//We need image and canvas for converting url to blob.
//Image is better then recieve blob through XHR request, because of crossOrigin mode
image.crossOrigin = "Anonymous";
image.onload = function(oEvent) {
//draw image on canvas
var canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
canvas.getContext('2d').drawImage(this, 0, 0, canvas.width, canvas.height);
// get image from canvas as blob
var binStr = atob( canvas.toDataURL(mime).split(',')[1] ),
len = binStr.length,
arr = new Uint8Array(len);
for (var i = 0; i < len; i++ ) {
arr[i] = binStr.charCodeAt(i);
}
var blob = new Blob( [arr], {type: mime} );
//IE not works with a.click() for downloading
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, name);
} else {
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = name;
a.click();
}
};
image.src = url;
}
document.querySelector("[download]").addEventListener("click", downloadHandler)
<button
data-name="file.png"
data-url="https://tpc.googlesyndication.com/simgad/14257743829768205599"
data-type="image/png"
download>
download
</button>
Another modern way for modern browsers (except Internet Explorer)
var downloadHandler = function(){
var url = this.dataset.url;
var name = this.dataset.name;
fetch(url).then(function(response) {
return response.blob();
}).then(function(blob) {
//IE and edge not works with a.click() for downloading
if (window.navigator && window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveOrOpenBlob(blob, name);
} else {
var a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = name;
a.click();
}
});
};
document.querySelector("[download]").addEventListener("click", downloadHandler)
<button
data-name="file.png"
data-url="https://tpc.googlesyndication.com/simgad/14257743829768205599"
download>
download
</button>
I'm able to rename base64 images with a save as input field.
I think your best bet is to create your own "save as" box. When a user clicks "download", display a "File Name: {input field}" and a save button. Have the save button change filename and then call the download function.
function save2() {
var gh = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADNQTFRFAAAAPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09EvTTBAAAABB0Uk5TAA8fLz9PX29/j5+vv8/f7/rfIY4AAARsSURBVHja7VvZkusqDAyrAQvQ/3/teZjExrHDZoGrbl0/z0RtLY1oya/X/8+Nh/NHzYuAGPRz9llERET1GACJiIgYngaAkmvNnwTgERHtgwDefngawDofgDkAwPlp4I4AzHQA/gggstk0jF/P7ELQ3wBQPBoBRPRzTyI8P/bBGvh79FMstFXCvDSAt0kHzyBYNv7jj/iAx48DEiwzEfj0AFi/EEw4F+2B/5mfXQsbB4ZDQOKGwM2ioE+4hUdEm3jCjzybRbw4gIXkrxfbySnqCfYhS48rG23fs/wRGYdcGIQv1PsOcIgTkp//xTcs4WbyTEjs67pmFfh8+3+X1s0Jy3z7rxezaZ9EdTjI2MC1MpA37LqN65kjdoJuPmtUUpC40NmvLy2WntM3OcH09RupE8KdMLjefufgBE1gvz2blnj/2pDY7wikSPold9M+dCVSWpDuln1HUMLuCfsHEndP2H+9uO+kJEfVaicNq+zin9udxY6gQcrRlFeNHUG1oCfpjpIjAtmaukQXHRabpJwdMNlFSzZFdL3Dv4WkrlH4lyH6Y6jOgj0BSPUGWV0InrQAztISr2UgahFe1r3XJgHRC9C+qhK3CqC/4H6Sm1XV64ApCKt5NegOgFTGGGPMIlnhx22NA64zhUsppTxVMtcuvY5hcCqX31DhgAu+EgZ+WLjSjoPJvF6mBH5lIFvC7wHBJ7kAAAByjFdkAvdDg0o7/PPByiOCSSIvbfhBo6HExvES/ftwjOs7v7iyoZCl0qhMhHWpDQoX9QvH/xJd+osriAbr9ZktEQONCm3yAD5EEU833YWIlgsA1PD5UwGAGz4DLAAIw0eAeQBs/CTaZi2o8VNYyAIwP2qAHsCSZYGR6xD5xtgPTwGeBzB+I0Xlj+Oajo2kCEK+GRqfg2sWwEAaKhCNLDdsRCkgnwLg8kEeDyDmLQwHoAp3w+EA1kJPPBoAL6lEYnAZmuLtfCwRbToZLwEYNP7X5Vs33NEFuI15BS6U7+auuydmGkoKXI1Kt9RlIZPHIIllLbfzWwboCm2AF480b7WUQkipDWySkhPlg7ggU9apWPFqkWzV2TZC1Am1a1UMltMWW8F6Xve4qpRCX86U3ZQkcEtFF79UKtW8RSJnsvr+IDK7N23HRScH+mrtWQ/RCF3D+DYOaM337bOKftvQ78iKps3fjbDIrkeX22cVLqAKAovVFfD1DzRi/V4AgbWmDMW8ivmO7Qto9FlV/FvGr5xsZilj3/hXI00UTPcKi6PYgkrXR5qnb/72ZuRho03fSF5E1xOGg7qvb5VPz2akTmcbnT48LExDCysycxitdGfRcWUbar2gvj59cDfqyH3NoMpNyt+k5r77t1B+tb/eZNzJtTt1y+4umXM49b9g1AmFUPvloDdzqsppDweA/RuSOoDLv6D7GvRAKPUP5ceo3DWbX4nFXm5iy8ubEfqCWiut22HDDqZcyBuP6zL6s0euLVzbBqunfWbFpTZmhfdjjVFy9seO/6nnH0Mpp/3TjvofAAAAAElFTkSuQmCC"
var a = document.createElement('a');
a.href = gh;
a.download = document.getElementById("input").value;
a.click()
}
Filename: <input id="input" name="input" placeholder="enter image name"></insput><button onclick="save2()">Save</button>
The above code will let you name the file for the user If you want the user to be able to name the file himself then you need to create an input field that updates a.download = 'imagetest.png'; through a listening function or onkeychange. I got it to work through "a.download = document.getElementById("input").value;". It's amazing what getElementByID can do.
Browsers are very limited in the ability to name files for people to download. I imagine it's a lack of functionality that has been overlooked.
If you want to take it a step further you can hide the "file name:" input field with display:hidden;. And you can have a "download" button with an onclick function that sets the "file name: input / save" div to no longer set to display:hidden;. This can also be done through getelementbyID.
I did however notice that there seems to be an issue with renaming the image with a URL instead of base64. So I tried integrating my code with yours though none of the code below seemed to work properly when clicking on your download link. I still think it's close enough that you may want to fiddle around with it if this is the route you want to go:
<script>
function save2() {
var gh = "https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png"
var a = document.createElement('a');
a.href = gh;
a.download = document.getElementById("input").value;
a.click()
}
function downloadit(){
var x = document.getElementById("input").value;
document.getElementById("dl").getAttribute("download") = x;
}
document.getElementById("dl").onclick = function() {
document.getElementById("dl").download= a.download = document.getElementById("input").value;
return false;
}
</script>
<a href="/image/1337">
<img src="//static.example.com/thumbnails/86fb269d190d2c85f6e0468ceca42a20.png"/>
</a>
<a onclick='downloadit()' id="dl" href="//static.example.com/full/86fb269d190d2c85f6e0468ceca42a20.png"
download="1337 - Hello world!.png">
Download
</a>
Filename: <input id="input" name="input" placeholder="enter image name"></insput><button onclick="save2()">Save</button>
Lastly, I was able to rename your example.com image with the following script. Though when I try it with a working googleimage it doesn't seem to rename. So you might want to dabble with this as well.
document.getElementById("dl").onclick = function() {
document.getElementById("dl").download=document.getElementById("input").value;
}
Filename: <input id="input" name="input" placeholder="enter image name"></input>
<a id="dl" href="//static.example.com/full/86fb269d190d2c85f6e0468ceca42a20.png"
download="1337 - Hello world!.png">
Download
</a>
I have a problem (or may be two) with saving files using HTML5 File API.
A files comes from the server as a byte array and I need to save it. I tried several ways described on SO:
creating blob and opening it in a new tab
creating a hidden anchor tag with "data:" in href attribute
using FileSaver.js
All approaches allow to save the file but with breaking it by changing the encoding to UTF-8, while the file (in current test case) is in ANSI. And it seems that I have to problems: at the server side and at the client side.
Server side:
Server side is ASP.NET Web API 2 app, which controller sends the file using HttpResponseMessage with StreamContent. The ContentType is correct and corresponds with actual file type.
But as can be seen on the screenshot below server's answer (data.length) is less then actual file size calculated at upload (file.size). Also here could be seen that HTML5 File object has yet another size (f.size).
If I add CharSet with value "ANSI" to server's response message's ContentType property, file data will be the same as it was uploaded, but on saving result file still has wrong size and become broken:
Client side:
I tried to set charset using the JS File options, but it didn't help. As could be found here and here Eli Grey, the author of FileUplaod.js says that
The encoding/charset in the type is just metadata for the browser, not an encoding directive.
which means, if I understood it right, that it is impossible to change the encoding of the file.
Issue result: at the end I can successfully download broken files which are unable to open.
So I have two questions:
How can I save file "as is" using File API. At present time I cannot use simple way with direct link and 'download' attribute because of serverside check for access_token in request header. May be this is the "bottle neck" of the problem?
How can I avoid setting CharSet at server side and also send byte array "as is"? While this problem could be hacked in some way I guess it's more critical. For example, while "ANSI" charset solves the problem with the current file, WinMerge shows that it's encoding is Cyrillic 'Windows-1251' and also can any other.
P.S. the issue is related to all file types (extensions) except *.txt.
Update
Server side code:
public HttpResponseMessage DownloadAttachment(Guid fileId)
{
var stream = GetFileStream(fileId);
var message = new HttpResponseMessage(HttpStatusCode.OK);
message.Content = new StreamContent(stream);
message.Content.Headers.ContentLength = file.Size;
message.Content.Headers.ContentType = new MediaTypeHeaderValue(file.ContentType)
{
// without this charset files sent with bigger size
// than they are as shown on image 1
CharSet = "ANSI"
};
message.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = file.FileName + file.Extension,
Size = file.Size
};
return message;
}
Client side code (TypeScript):
/*
* Handler for click event on download <a> tag
*/
private downloadFile(file: Models.File) {
var self = this;
this.$service.downloadAttachment(this.entityId, file.fileId).then(
// on success
function (data, status, headers, config) {
var fileName = file.fileName + file.extension;
var clientFile = new File([data], fileName);
// here's the issue ---^
saveAs(clientFile, fileName);
},
// on fail
function (error) {
self.alertError(error);
});
}
My code is almost the same as in answers on related questions on SO: instead of setting direct link in 'a' tag, I handle click on it and download file content via XHR (in my case using Angularjs $http service). Getting the file content I create a Blob object (in my case I use File class that derives from Blob) and then try to save it using FileSaver.js. I also tried approach with encoded URL to Blob in href attribute, but it only opens a new tab with a file broken the same way. I found that the problem is in Blob class - calling it's constructor with 'normal' file data I get an instance with 'wrong' size as could be seen on first two screenshots. So, as I understand, my problem not in the way I try to save my file, but in the way I create it - File API
I want to export image which is displayed on web page. This image is stored in Sql image data type. While displaying image I am converting the image to Base64String.
Image1.ImageUrl = "data:image/jpg;base64," & Convert.ToBase64String(imgPhoto)
While exporting page, image is not displaying in word document file.
I can not store image on the server because of security reason.
below code is for export to word file.
Response.AddHeader("content-disposition", "attachment;filename=Test.doc")
Response.Cache.SetCacheability(HttpCacheability.NoCache)
Response.ContentType = "application/ms-word "
Response.Charset = ""
Dim stringWrite As New System.IO.StringWriter()
Dim htmlWrite As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite)
' Create a form to contain the grid
ControlID.RenderControl(htmlWrite)
Dim stringWrite1 As New System.IO.StringWriter()
Dim htmlWrite1 As System.Web.UI.HtmlTextWriter = New HtmlTextWriter(stringWrite1)
' Create a form to contain the grid
ImageLogo.RenderControl(htmlWrite1)
Response.Write(stringWrite1.ToString() & stringWrite.ToString())
Response.[End]()
You really aren't creating a Word document, just rendering the HTML to a word MIME type. I don't believe word supports the data:image definition since that is much newer than the pre-2007 word format. Instead, try the OpenXML SDK. Although it creates Word 2007+ documents only, most people can view them. The OpenXML SDK will enable you to create a real word doc and create an image from the binary image data.
http://www.microsoft.com/en-us/download/details.aspx?id=30425
http://msdn.microsoft.com/en-us/library/office/bb448854%28v=office.15%29.aspx
I can't get through this problem though it must be only a very small syntax problem, as you will see: In fact, I'm searching for just a little piece of syntax, unless what I intend to do would be impossible (But I can see no reason why it should be impossible...).
I have written a function to encode an image into Base64 on server side, because I want to store numerous images into an array:
So, with Base64 I can download images as ordinary strings that I can organize in an array, then put them into an object just when I have chosen the right image and the right moment, without having to refer to the server again, so that the user doesn't have to wait.
Then I do something like this:
First phase:
function download64(imageUrl) //->string
{ // ask the server to send the 'imageUrl' as a base64 string
var tx = DoTheJob(); // ...connect through ajax and download the image converted in base64 as a string in var 'tx'
return tx
}
At this stage, I'm holding the image in the 'tx' Base64-string on client side.
Somewhat later I want to display my image in the div called "cadre", so I do the following:
Second phase:
I just have to call the "display64" function to set my image into the "cadre" div-object on the screen:
display64("cadre",tx);
using this function:
function display64(destinationDiv,imgText64) //->void
{ // display 'imgText64' into destinationDiv
var oImg = "<img alt='' src='data:image/jpg;base64," + imgText64 + "'>";
var x = document.getElementById(destinationDiv);
x.innerHTML = oImg;
}
Now the image is displayed. Unfortunately, this works well only with Firefox, because Internet Explorer 8 can't read Base64 images above 32Kb! And in my entreprise, we use IE 8 only!
Then I dropped my base64 encoder and decided to fetch the image as a binary string, which I could manage though I initially had a problem with nul character.
Now, I'm here with my binary string containing the exact copy of the source JPG file (including zeros that I have encoded on server side then restored on client side). So, what I need now is the simple function 'displayBin', but I can't find the syntax on the web:
function displayBin(destinationDiv,imgTextBin) //->void
{ // display 'imgTextBin' into destinationDiv
var oImg = "<img alt='' src='??????? + imgTextBin + "'>"; // What's the syntax here, please?
var x = document.getElementById(destinationDiv);
x.innerHTML = oImg;
}
Can anyone help ? Thanks a lot.
If I understand your question your are wanting to store images so you do not have to connect back with the server. One way of doing this is to preload the images like var img=new Image; img.src='path'; You could load all of the images into an array and you could then add them to the page as necessary. There is a lot out there on image preloading since that seems what your trying to accomplish.