Chrome, Firefox converting ":" to "-" and "_" respectively in their file save dialog - javascript

I am trying to save a file using FileSaver library which will save the file using Chrome's and Firefox's Save As dialog.
Ex: I have certain filename like testing:testing1:testing2.csv.
Now when the Save As dialog pops up, I am seeing filename converted to
testing-testing1-testing2.csv for Chrome
and
testing_testing1_testing2.csv for Firefox.
Is there any way we can suppress this conversion of characters?
Thanks

No.
File names can't contain, among other characters, the colon : (On Windows machines). If you want to make sure your application is compatible with Windows, keep that in mind.
These are the disallowed characters:
\/:*?"<>|
Firefox & Chrome probably replace all of those by the dash / underscore.

The filename is merely a suggestion. RFC 2616 states that:
19.5.1 Content-Disposition
The Content-Disposition response-header field has been proposed as a
means for the origin server to suggest a default filename if the user
requests that the content is saved to a file. This usage is derived
from the definition of Content-Disposition in RFC 1806 [35].
RFC 1806 further states that:
It is important that the receiving MUA not blindly use the suggested
filename. The suggested filename SHOULD be checked (and possibly
changed) to see that it conforms to local filesystem conventions, does
not overwrite an existing file, and does not present a security
problem (see Security Considerations below).
Long story short, different file systems have different restrictions on filenames. The browser is free to fix the filename if it cannot be used as-is.

Related

web security: What happens when Content-Disposition is not supplied?

I am allowing users to download files from my application. For that I am explicitly setting "Content-Disposition" as "inline" or "attachment" based on the type of file. This is kinda manual right now. So, for pdf files i set it to "inline" but for html files I set it to "attachment".
Is there a way to automatically decide the value of "Content-Disposition" in express based on file type ?
If I do not send a "Content-Disposition" header, it seems to me currently that the request is treated like it has "Content-Disposition: inline" . Is this observation correct, or is there something more to it?
If by default browser tries to execute/preview the files (based on point 2), what does it mean for security when you allow downloading html files which can execute javascript?
Is there a way to automatically decide the value of "Content-Disposition" in express based on file type ?
You could write middleware that inspects the response and modifies it.
If I do not send a "Content-Disposition" header, it seems to me currently that the request is treated like it has "Content-Disposition: inline" . Is this observation correct, or is there something more to it?
See MDN which says: "The first parameter in the HTTP context is either inline (default value, indicating it can be displayed inside the Web page, or as the Web page)…"
If by default browser tries to execute/preview the files (based on point 2), what does it mean for security when you allow downloading html files which can execute javascript?
Not a lot unless you are serving up JavaScript that you (the website author) do not trust.
If you need to serve HTML documents which might contain JavaScript you don't trust then serve them from a different origin (to use the Same Origin Policy to sandbox them) and/or implement a Content Security Policy to ban them from executing JavaScript.

How does the browser process image sources?

[UPDATE] I found two links useful to me:
http://mrcoles.com/blog/canvas-composite-operations-demo-animation/
http://tutorials.jenkov.com/html5-canvas/composition.html
Recently when I learn canvas, I find there is more than one way to specify the image src:
You can give a image-URI, like : www.XYZ.com/abc.png
You can give a data-URI, like: data:image/svg+xml;base64,'+ hexcode;
You can give a data-URI from canvas like: canvas.toDataURL("image/png");
I am a little confused about what the difference among them and wondering how browser processes them?
Thanks
It's simply a matter of what the browser supports. The browser will look at the protocol header of the string and if it recognizes it try to interpret it. For example:
If it starts with "http://" or "https://" it will parse the rest of the string with that as a basis. Then try to connect using the HTTP(S) protocol to the server and communicate over this protocol. The protocol itself is specified in RFCs. If all OK, then data is transferred from server to browser which then goes to the next step interpreting the received data itself (this can happen during or after the data has loaded completely).
If the string starts with "data:" the browser will assume a Data-URI protocol (if it supports this protocol). If not, it will consider the source invalid. As it does not need to connect to any external resources in this case, it will validate the content of it and use it if valid. Data-URI will be converted to binary data (the base-64 representation will be converted back to binary form).
(2. and 3. are the same BTW. It's not hexcode that is appended, but a base-64 encoded string, ie. ASCII representation. Other representations are possible but not common).
Then there are other protocols which the browser may support, such as Blob-URL and perhaps some browser will allow FTP (ftp://), and some allow file:// given certain restrictions.

Download a file by changing window.location w/ Safari

I have an offline html file that generates and saves a CSV by setting window.location to
data:text/csv;base64,Intfa2V5fSIsInt...
However, in Safari this just brings up the CSV in the browser.
Setting the url to:
data:application/csv;base64,Intfa2V5fSIsInt...
forces Safari to download the file - but it gets a generic file name of just 'Unknown-3'. Is there a way to specify the file name?
First, a warning:application/csv isn't a valid MIME type, so the fact that it "works" for you in this case is purely an implementation quirk that could very well change in the future. (For example, Safari displays application/octet-stream, which I'd expect to download.)
HTML5 does have a new <a download="file.name"> attribute. This forces the browser to download the file to disk; it uses the attribute's value as the default file name. It does work in conjunction with a data URI or a blob URI. (Demo)
However, it is currently only supported by Chrome (14+). Safari 5.1 ignores the attribute.
A possible alternative is to use the Filesystem API, but that gives you a sandboxed folder to work with. You can't—for example—save a file directly to the user's Documents folder. Instead, you can write a file to the sandbox and then redirect to file on the new filesystem schema:
location.assign('filesystem:http://example.com/temporary/somefile.csv');
This should invoke the UA's download mechanism (with the right filename!), but I haven't tested this, so it is possible Safari will just display the file anyway.
According to the RFC 2397 no. There is no way.
Also read this related question.

Save XML file on my machine with XMLDom object save()

I'm not able to save to the xml file on my machine.
I have noticed that node value is changed temprorily but not permanent in xml file.
P.S : This is only a simple HTML file with javascript
It is giving me an error "Permission Denied"
function viewBookDetails() {
var xmlDoc = xmlLoader("cart.xml");
//var x = xmlDoc.getElementsByTagName("dogHouse")[0];
var x = xmlDoc.documentElement;
var newel = xmlDoc.createElement("essy");
x.appendChild(newel);
alert(x.xml);
xmlDoc.save("cart.xml");
}
is it not possible to save xml file on my machine?
Thank you,
In general, browser JavaScript has no I/O API and cannot read or write to the client filesystem since that could be a security loophole. I haven't seen or used the save() method before but it looks like it's an IE specific extension to the XML DOM. If you must use it, this thread might provide the solution, the answer that worked for the OP there suggested:
I haven't proofed your code but here is something you might want to try. I am taking a shot in the dark that you are using this on a Windows OS since you are using IE and from the sound of the error. Just take your html file that you have and rename it the whatever.hta and it will then be able to write to the xml file and save.
Also, the documentation for the method says the following for when the argument is a string (as in your code snippet):
String
Specifies the file name. This must be a file name rather than a URL. The file is created, if necessary, and the contents are replaced entirely with the contents of the saved document. This mode is not intended for use from a secure client, such as Microsoft Internet Explorer.
From the forum posts (links below) that deal with the same issue, I gleaned the following:
This is an IE specific extension and so will only work in IE
There are obviously security restrictions in place so you shouldn't be able to do this 'out of the box'
One workaround that crops up often is to rename the file extension to .hta (Hypertext Application) instead of .html
I'm not sure but there might also be some workarounds by changing the permissions for the security zones your application runs in
References:
http://www.codingforums.com/showthread.php?t=25048
http://p2p.wrox.com/xml/4053-error-using-xml-save-method.html
http://www.daniweb.com/web-development/javascript-dhtml-ajax/threads/204995

Why do so many Javascript scripts append random numbers to things? Collision?

I've been learning JavaScript recently, and I've seen a number of examples (Facebook.com, the Readability bookmarklet) that use Math.rand() for appending to links.
What problem does this solve? An example parameter from the Readability bookmarklet:
_readability_script.src='http://lab.arc90.com/....script.js?x='+(Math.random());
Are there collisions or something in JavaScript that this is sorting out?
As Rubens says, it's typically a trick employed to prevent caching. Browsers typically cache JavaScript and CSS very aggressively, which can save you bandwidth, but can also cause deployment problems when changing your scripts.
The idea is that browsers will consider the resource located at http://www.example.com/something.js?foo different from http://www.example.com/something.js?bar, and so won't use their local cache to retrieve the resource.
Probably a more common pattern is to append an incrementing value which can be altered whenever the resource needs to change. In this way, you benefit by having repeat requests served by the client-side cache, but when deploying a new version, you can force the browser to fetch the new version.
Personally, I like to append the last-modified time of the file as as a Unix timestamp, so I don't have to go hunting around and bumping version numbers whenever I change the file.
Main point is to avoid browser caching those resources.
This will ensure that the script is unique and will not cached as a static resource since the querystring changes each time.
This is because Internet Explorer likes to cache everything, including requests issued via JavaScript code.
Another way to do this, without random numbers in the URL, is to add Cache-Control headers to the directories with the items you don't want cached:
# .htaccess
Header set Cache-Control "no-cache"
Header set Pragma "no-cache"
Most browsers respect Cache-Control but IE (including 7, haven't tested 8) only acknowledge the Pragma header.
Depending on how the browser chooses to interpret the caching hints of a resource you might not get the desired effect if you just asked the browser to change the url to a url it has previously used. (most mouse-over image buttons rely on the fact that the browser will reuse the cached resource for speed)
When you want to make sure that the browser gets a fresh copy of the resource (like a dynamic stock ticker image or the like) you force the browser to always think the content is newby appending either the date/time or a every-incresing number or random gargabe).
There is a tool called squid that can cache web pages. Using a random number will guarantee that request will not be ached by an intermediate like this. Even with Header set Cache-Control "no-cache" you may still need to add a random number to get through something like "squid".

Categories