Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Could someone suggest a library to work with paths like : /a/b/c.jpg or http://asdf/sdf/fd.jpg
I need get directory or just filename string, similar to what the following PHP filesystem functons offers:
dirname
basename
Have a look at the parseURI function of Flagrant Badassery's blog. It can parse any well formed URIs.
Using jQuery or any Javascript you cannot list a directory and the files within it for security reasons.
You can get a filename using regex by using:
var path = "/a/b/c.jpg",
filename = path.replace(/^.*(\\|\/|\:)/, '');
To get the extension and basename of a file you can use (Note: you will need to use this with the above code as well):
var basename = filename.substr(0, filename.lastIndexOf( "." )),
extension = filename.substr(filename.lastIndexOf( "." )+1, filename.length);
If you really need to get a directories list, you can get it with PHP and return it to the client with an AJAX request. This is definitely not recommended because it could very easily be abused to list secure or private files. The only instance I would recommend this is if the directory you are listing will definitely only ever contain files you know are safe to display such as a directory of images that have been uploaded. To do this you would do:
PHP file in directory (index.php)
<?
// Set JSON headings
header('Cache-Control: no-cache, must-revalidate');
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Content-type: application/json');
// The directory to list
$this_directory = opendir(".");
// Loop through each file
while($file_name = readdir($this_directory)) {
// Add the files to an array
if($file_name != "." && $file_name != "..") $return_array[] = $file_name;
}
// Return the array as JSON
echo json_encode($return_array);
// Close the directory
closedir($this_directory);
?>
Javascript
// Get the JSON from the PHP file
$.getJSON("img/", function(data){
// Loop through each file
for(var i = 0, j = data.length; i < j; i++) {
// Do whatever you want with the filename
console.log(data[i]);
}
});
Again, only do this on a directory that you know will contain files that are OK to display to the world. NEVER pass in to the PHP file an option to specify which directory to list. For example, don't allow the PHP to take an input such as "/home/site.com/sensitive_data/" because it will allow an attacker to arbitrarily list any directory on your server.
Related
The short story:
Is there simple way to normalize file path in JavaScript, like in Java we have Paths.get("/a/b/../c").normalize() so /a/../../c would become /c. I seen many same questions here, but they are Node.js solutions, and I need pure JS or JQuery approach so it can be used in browser.
The long story:
I have a file server with web UI, that allows to browse files and download them. UI is written in spring and accessible at mysite.com/ui/
The file storage located at mysite.com/files/ which is plain Apache directory, so its possible to get direct link to file.
The real storage directory on server is /var/www/files
Path passing to back-end as mysite.com/ui/?path=/a/../../c, so back-end will normalize path variable separately to /c and then append it to base dir and so retrieving content of /home/storage/c, so it works perfectly.
The problem comes when user tries to download file like this with direct link. I.e. if user tries to download /a/../../c/d file from file server root, it appending to base storage url, which mysite.com/files/, and it becomes mysite.com/files/a/../../c/d so it will point to /var/www/d instead of /var/www/files/d so file can't be downloaded even if it is visible from web UI.
So I need to normalize relative file path first on front-end like on back-end when retrieving content of directory but I don't know how it can be done in JS. Is there function for it, or I have to write my own one?
So I ended up writing my own function on JS. It might be not what "path normalization" stands for, but anyway its exactly what I need
function normalizePath(path) {
// remove multiple slashes
path = path.replace(/\/+/g, '/');
// remove leading slash, will be added further
if (path.startsWith("/"))
path = path.substring(1)
// remove trailing slash
if (path.endsWith("/"))
path = path.slice(0, -1);
let segments = path.split("/");
let normalizedPath = "/";
for (let segmentIndex = 0; segmentIndex < segments.length; segmentIndex++) {
if (segments[segmentIndex] === "." || segments[segmentIndex] === "") {
// skip single dots and empty segments
continue;
}
if (segments[segmentIndex] === "..") {
// go up one level if possible
normalizedPath = normalizedPath.substring(0, normalizedPath.lastIndexOf("/") + 1);
continue;
}
// append path segment
if (!normalizedPath.endsWith("/"))
normalizedPath = normalizedPath + "/"
normalizedPath = normalizedPath + segments[segmentIndex];
}
return normalizedPath;
}
Still, I won't mark this as accepted answer as it's more of a quick fix, and I'm not JS expert so it definitely must be more elegant solution.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I am still very new at web development, I need some suggestions please. I am busy creating a page with a date selector, then I have a folder with one file saved every day. What I am trying to do is: The user needs to select the date of the file he wants and click download and the file saved on that date needs to be downloaded. Can someone please give me an idea how I can get this to work. I have tried some things with JavaScript and php and could not get a working solution.
This code should do the job.
First we scan path provided and list all files, then check creation date and find our target file.
<?php
$Path = './'; // Set path of files here
$TargetDate = '2016-08-11'; // We find the first file with thi date
$TargetFile = null; // Store result here
// Lets Do It
foreach (glob("$Path/*") as $File) {
$Stat = stat($File);
if (date("Y-m-d", $Stat['ctime']) == $TargetDate) {
$TargetFile = $File;
break;
}
}
// Your File!
if (is_null($TargetFile)) {
echo 'No file found';
} else {
echo $TargetFile;
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm writing a Web application that needs to store JSON data in a small, fixed-size server-side cache via AJAX (think: Opensocial quotas). I do not have control over the server.
I need to reduce the size of the stored data to stay within a server-side quota, and was hoping to be able to gzip the stringified JSON in the browser before sending it up to the server.
However, I cannot find much in the way of JavaScript implementations of Gzip. Any suggestions for how I can compress the data on the client side before sending it up?
Edit There appears to be a better LZW solution that handles Unicode strings correctly at http://pieroxy.net/blog/pages/lz-string/index.html (Thanks to pieroxy in the comments).
I don't know of any gzip implementations, but the jsolait library (the site seems to have gone away) has functions for LZW compression/decompression. The code is covered under the LGPL.
// LZW-compress a string
function lzw_encode(s) {
var dict = {};
var data = (s + "").split("");
var out = [];
var currChar;
var phrase = data[0];
var code = 256;
for (var i=1; i<data.length; i++) {
currChar=data[i];
if (dict[phrase + currChar] != null) {
phrase += currChar;
}
else {
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
dict[phrase + currChar] = code;
code++;
phrase=currChar;
}
}
out.push(phrase.length > 1 ? dict[phrase] : phrase.charCodeAt(0));
for (var i=0; i<out.length; i++) {
out[i] = String.fromCharCode(out[i]);
}
return out.join("");
}
// Decompress an LZW-encoded string
function lzw_decode(s) {
var dict = {};
var data = (s + "").split("");
var currChar = data[0];
var oldPhrase = currChar;
var out = [currChar];
var code = 256;
var phrase;
for (var i=1; i<data.length; i++) {
var currCode = data[i].charCodeAt(0);
if (currCode < 256) {
phrase = data[i];
}
else {
phrase = dict[currCode] ? dict[currCode] : (oldPhrase + currChar);
}
out.push(phrase);
currChar = phrase.charAt(0);
dict[code] = oldPhrase + currChar;
code++;
oldPhrase = phrase;
}
return out.join("");
}
I had another problem, I did not want to encode data in gzip but to decode gzipped data.
I am running javascript code outside of the browser so I need to decode it using pure javascript.
It took me some time but i found that in the JSXGraph library there is a way to read gzipped data.
Here is where I found the library: http://jsxgraph.uni-bayreuth.de/wp/2009/09/29/jsxcompressor-zlib-compressed-javascript-code/
There is even a standalone utility that can do that, JSXCompressor, and the code is LGPL licencied.
Just include the jsxcompressor.js file in your project and then you will be able to read a base 64 encoded gzipped data:
<!doctype html>
</head>
<title>Test gzip decompression page</title>
<script src="jsxcompressor.js"></script>
</head>
<body>
<script>
document.write(JXG.decompress('<?php
echo base64_encode(gzencode("Try not. Do, or do not. There is no try."));
?>'));
</script>
</html>
I understand it is not what you wanted but I still reply here because I suspect it will help some people.
We just released pako https://github.com/nodeca/pako , port of zlib to javascript. I think that's now the fastest js implementation of deflate / inflate / gzip / ungzip. Also, it has democratic MIT licence. Pako supports all zlib options and its results are binary equal.
Example:
var inflate = require('pako/lib/inflate').inflate;
var text = inflate(zipped, {to: 'string'});
I ported an implementation of LZMA from a GWT module into standalone JavaScript. It's called LZMA-JS.
Here are some other compression algorithms implemented in Javascript:
Huffman
LZ77
I did not test, but there's a javascript implementation of ZIP, called JSZip:
https://stuk.github.io/jszip/
I guess a generic client-side JavaScript compression implementation would be a very expensive operation in terms of processing time as opposed to transfer time of a few more HTTP packets with uncompressed payload.
Have you done any testing that would give you an idea how much time there is to save? I mean, bandwidth savings can't be what you're after, or can it?
Most browsers can decompress gzip on the fly. That might be a better option than a javascript implementation.
You can use a 1 pixel per 1 pixel Java applet embedded in the page and use that for compression.
It's not JavaScript and the clients will need a Java runtime but it will do what you need.
This question already has answers here:
How to get full path of selected file on change of <input type=‘file’> using javascript, jquery-ajax?
(14 answers)
Closed 9 years ago.
I have created <input type="file" name="files" id="fld1" webkitdirectory > in an html file.
i can get the files using
var imageFiles = document.getElementById("fld1"),
filesLength = imageFiles.files.length;
for (var i = 0; i < filesLength; i++) {
alert(imageFiles.files[i].name);
}
How can i get the full path of the directory selected in javascript . please help
I want to show all the image files present in any folder using jquery slider. i can get the name of the files present in that folder but i cannot get the full path of the folder. how can i get it.
i have done this to get the file path but it only worked in IE
<script language="JavaScript">
function GetDirectory() {
strFile = document.MyForm.MyFile.value;
intPos = strFile.lastIndexOf("\\");
strDirectory = strFile.substring(0, intPos);
alert(strFile + '\n\n' + strDirectory);
return false;
}
</script>
For obvious security reasons you cannot do that. Browsers won't allow you to access and explore the file system of the client computers using javascript. Some browsers will simply return some fake path to the file.
Check File API documentation, the File section gives details about the File object.
Quoting from the doc:
The name of the file; on getting, this must return the name of the
file as a string. There are numerous file name variations on different
systems; this is merely the name of the file, without path
information. On getting, if user agents cannot make this information
available, they must return the empty string.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm a member of a team with more than 20 developers. Each developer works on a separate module (something near 10 modules). In each module we might have at least 50 CRUD forms, which means that we currently have near 500 add buttons, save buttons, edit buttons, etc.
However, because we want to globalized our application, we need to be able to translate texts in our application. For example, everywhere, the word add should become ajouter for French users.
What we've done till now, is that for each view in UI or Presentation Layer, we have a dictionary of key/value pairs of translations. Then while rendering the view, we translate required texts and strings using this dictionary. However, this approach, we've come to have something near 500 add in 500 dictionaries. This means that we've breached DRY principal.
On the other hand, if we centralize common strings, like putting add in one place, and ask developers to use it everywhere, we encounter the problem of not being sure if a string is already defined in the centralized dictionary or not.
One other options might be to have no translation dictionary and use online translation services like Google Translate, Bing Translator, etc.
Another problem that we've encountered is that some developers under the stress of delivering the project on-time can't remember the translation keys. For example, for the text of the add button, a developer has used add while another developer has used new, etc.
What is the best practice, or most well-known method for globalization and localization of string resources of an application?
As far as I know, there's a good library called localeplanet for Localization and Internationalization in JavaScript. Furthermore, I think it's native and has no dependencies to other libraries (e.g. jQuery)
Here's the website of library: http://www.localeplanet.com/
Also look at this article by Mozilla, you can find very good method and algorithms for client-side translation: http://blog.mozilla.org/webdev/2011/10/06/i18njs-internationalize-your-javascript-with-a-little-help-from-json-and-the-server/
The common part of all those articles/libraries is that they use a i18n class and a get method (in some ways also defining an smaller function name like _) for retrieving/converting the key to the value. In my explaining the key means that string you want to translate and the value means translated string.
Then, you just need a JSON document to store key's and value's.
For example:
var _ = document.webL10n.get;
alert(_('test'));
And here the JSON:
{ test: "blah blah" }
I believe using current popular libraries solutions is a good approach.
When you’re faced with a problem to solve (and frankly, who isn’t
these days?), the basic strategy usually taken by we computer people
is called “divide and conquer.” It goes like this:
Conceptualize the specific problem as a set of smaller sub-problems.
Solve each smaller problem.
Combine the results into a solution of the specific problem.
But “divide and conquer” is not the only possible strategy. We can also take a more generalist approach:
Conceptualize the specific problem as a special case of a more general problem.
Somehow solve the general problem.
Adapt the solution of the general problem to the specific problem.
- Eric Lippert
I believe many solutions already exist for this problem in server-side languages such as ASP.Net/C#.
I've outlined some of the major aspects of the problem
Issue: We need to load data only for the desired language
Solution: For this purpose we save data to a separate files for each language
ex. res.de.js, res.fr.js, res.en.js, res.js(for default language)
Issue: Resource files for each page should be separated so we only get the data we need
Solution: We can use some tools that already exist like
https://github.com/rgrove/lazyload
Issue: We need a key/value pair structure to save our data
Solution: I suggest a javascript object instead of string/string air.
We can benefit from the intellisense from an IDE
Issue: General members should be stored in a public file and all pages should access them
Solution: For this purpose I make a folder in the root of web application called Global_Resources and a folder to store global file for each sub folders we named it 'Local_Resources'
Issue: Each subsystems/subfolders/modules member should override the Global_Resources members on their scope
Solution: I considered a file for each
Application Structure
root/
Global_Resources/
default.js
default.fr.js
UserManagementSystem/
Local_Resources/
default.js
default.fr.js
createUser.js
Login.htm
CreateUser.htm
The corresponding code for the files:
Global_Resources/default.js
var res = {
Create : "Create",
Update : "Save Changes",
Delete : "Delete"
};
Global_Resources/default.fr.js
var res = {
Create : "créer",
Update : "Enregistrer les modifications",
Delete : "effacer"
};
The resource file for the desired language should be loaded on the page selected from Global_Resource - This should be the first file that is loaded on all the pages.
UserManagementSystem/Local_Resources/default.js
res.Name = "Name";
res.UserName = "UserName";
res.Password = "Password";
UserManagementSystem/Local_Resources/default.fr.js
res.Name = "nom";
res.UserName = "Nom d'utilisateur";
res.Password = "Mot de passe";
UserManagementSystem/Local_Resources/createUser.js
// Override res.Create on Global_Resources/default.js
res.Create = "Create User";
UserManagementSystem/Local_Resources/createUser.fr.js
// Override Global_Resources/default.fr.js
res.Create = "Créer un utilisateur";
manager.js file (this file should be load last)
res.lang = "fr";
var globalResourcePath = "Global_Resources";
var resourceFiles = [];
var currentFile = globalResourcePath + "\\default" + res.lang + ".js" ;
if(!IsFileExist(currentFile))
currentFile = globalResourcePath + "\\default.js" ;
if(!IsFileExist(currentFile)) throw new Exception("File Not Found");
resourceFiles.push(currentFile);
// Push parent folder on folder into folder
foreach(var folder in parent folder of current page)
{
currentFile = folder + "\\Local_Resource\\default." + res.lang + ".js";
if(!IsExist(currentFile))
currentFile = folder + "\\Local_Resource\\default.js";
if(!IsExist(currentFile)) throw new Exception("File Not Found");
resourceFiles.push(currentFile);
}
for(int i = 0; i < resourceFiles.length; i++) { Load.js(resourceFiles[i]); }
// Get current page name
var pageNameWithoutExtension = "SomePage";
currentFile = currentPageFolderPath + pageNameWithoutExtension + res.lang + ".js" ;
if(!IsExist(currentFile))
currentFile = currentPageFolderPath + pageNameWithoutExtension + ".js" ;
if(!IsExist(currentFile)) throw new Exception("File Not Found");
Hope it helps :)
jQuery.i18n is a lightweight jQuery plugin for enabling internationalization in your web pages. It allows you to package custom resource strings in ‘.properties’ files, just like in Java Resource Bundles. It loads and parses resource bundles (.properties) based on provided language or language reported by browser.
to know more about this take a look at the How to internationalize your pages using JQuery?