How to pass multiple filenames for php download - javascript

I am trying to implement download functionality in PHP. A user can download single or multiple files. If user try to download single file, the file gets downloaded normally. If user tries to download multiple files, all the files will be converted to zip and get downloaded.
But my problem is how to pass the gruop of filenames along with their paths. For a single file I passed it using
window.location = directories_path + "?action=download&files="+download;
download can be an array where I can pass files. But I am unable to pass them. My url appeared alike
localhost/proj/Base?action=download&files=[object Object]
I even tried with AJAX passing file names in json format. But it didn't work.
My JS code for the download process
$("input:checked").each(function(){
if($(this).siblings('a').length > 0)
{
download.push({
name: $(this).siblings('a').text(),
path: $(this).siblings('a').attr('href'),
});
}
});
if( checked == 0 ) {
alert("Please select any file to download");
} else {
window.location = directories_path + "?action=download&files="+download;
}
My php code for downloading single file is
header('Content-Type: application/octet-stream');
header('Content-Length: '.filesize($file));
header('Content-Disposition: attachment; filename='.$file);
header('Content-Transfer-Encoding: binary');
readfile($file);
My question is Is there any way so that I can pass an array of objects(filename and filepath) in url so that I can download the files correspondingly. Thanks

Thanks #ADyson and remaining all others for help. Finally this is how I implemented it. I am posting it so that it might be useful to someone.
I made an AJAX post request and returned the link. And finally changed the window.location to that specific link for multiple files. But for single file downloads, It may not be possible sometimes. For Eg: If you change the location to PNG image. The browser opens the PNG image instead of downloading it. So, I preferred HTML anchor download tag for single file downloads.
This is my JQuery code:
$(".uploaded_files").on('click', '#download', function(event){
download = [];
$("input:checked").each(function(){
if($(this).siblings('a').length > 0)
{
download.push({
name: $(this).siblings('a').text(),
path: $(this).siblings('a').attr('href'),
});
}
});
if( checked == 0 ) {
alert("Please select any file to download");
} else if( checked == 1) {
$("body").append($(''));
console.log(download);
document.getElementById('download_single').click();
$("a#download_single").remove();
} else {
alert("The download begins in few seconds");
$.post('Base.php', {
action: 'download',
files: download //array of objects of files
}, function(link) {
window.location = link;
});
}
});
This is my PHP code for downloading multiple files
$zip = new ZipArchive();
$zip_file = 'tmp/'.md5("download".rand(1,1000000)."zipfile").".zip";
if( $zip->open($zip_file, ZipArchive::CREATE))
{
foreach($files as $file)
{
$file['path'] = explode('uploads/', $file['path'])[1];
$file['path'] = 'uploads/'.$file['path'];
$zip->addFile($file['path'], $file['name'] );
}
$zip->close();
header('Content-disposition: attachment; filename='.$zip_file.'');
header('Content-type: application/zip');
echo "http://localhost/".$zip_file;
die();

Related

How can I run a php script when a user clicks a link without redirecting to that particular php page, and download an mp3 file at the same time?

I have an mp3 file whose downloads value am counting and updating well in a MySQL database when I run my php script by going to the scripts address in the address bar like this https://groupkse.net/music_files/countDownloads.php?id=3. My issue is I want to run this php script without redirecting my browser to this location, when a link is clicked to download that mp3. NB: The mp3 is in the same directory with the countDownloads.php and the page containing the link is in a different directory, but on the same server, i.e. https://groupkse.net/songReleaseHtml/megaMuQuarantine.php
Code from countDownloads.php is below:
<?php
//Make connection with database
$conn = mysqli_connect("localhost", "groupkse_music_admin", "my_Password", "groupkse_music_downloads");
//Check connection
if (mysqli_connect_errno()) {
printf("Connection failed: %s\n", mysqli_connect_error());
exiit();
}
//Passing which song needs download increment
$incomingData = $_SERVER['QUERY_STRING'];
$data = substr($incomingData, strpos($incomingData, 'id=') + 3);
$id = mysqli_real_escape_string($conn, $data);
//echo "$id";
$query = "UPDATE `music_downloads` SET `downloads_number` = `downloads_number` + 1 WHERE `Id` = '$id'";
mysqli_query($conn, $query);
?>
And code from my link in the megaMuQuarantine.php:
Download MP3
Download MP3
Add this input to point to the php file that counts downloads.
<input type="hidden" id="downloadCounter" value="LINK TO COUNTER" />
Put this at the bottom of your web page:
<script>
document.getElementById("dButton").addEventListener("click", function(event){
var xhttp;
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
location.relod;
}
};
xhttp.open("GET", document.getElementById("downloadCounter").value(), true);
xhttp.send();
});
</script>
To execute a PHP code without actual page action requires AJAX as pointed out by #nikistag; security issues being secondary as per now. For file downloads, this can be tricky and I would advice that you go with the 'download' attribute for html5. If such links with download attribute is clicked, it will download the file - major file types already covered. Now figure out a way to create this dynamic link; you can easily do this with jQuery or pure JS and perform auto-click on it when your button is clicked.
//hide this somewhere in your current page
<a id="choiceMusic" href="../music_files/default_music.mp3" download>
//to change href according to choice, use something like this in that master function
var currentMusic = "../music_files/"+ chosenOne.mp3;
$("#choiceMusic").attr("href", currentMusic);
//when ready to call this; //if fails, try: $('#choiceMusic')[0].click(function(){});
$('#choiceMusic').trigger('click');
Ensure that all these happen after the document if fully ready
$(document).ready(function(){
//safe to do your staff now,
});
Now call your master function and don't forget to include your Ajax function for updates
I put together the information from the above answers and came up with a solution that works for me. I hope it's a practice that is allowed!
Made two interdependent links with one of them invisible:
Download MP3
<a href="../music_files/mu_quarantine.mp3" download id="downloadSong" hidden></a>
Some AJAX and another JavaScript function to run my PHP file in the background and auto click the invisible link:
var dButton = document.getElementById("dButton"),
hidden_dLink = document.getElementById("downloadSong");
// Act on clicks to a elements
function downloadMP3() {
// Clicks the hidden anchor tag
hidden_dLink.click();
}
$(document).ready(function () {
$('#dButton').on('click', function () {
$.ajax({
url: 'https://groupkse.net/music_files/countDownloads.php?id=3',
method: 'GET',
xhrFields: {
responseType: 'blob'
},
success: function (data) {
var a = document.createElement('a');
var url = window.URL.createObjectURL(data);
a.href = url;
a.download = 'file.mp3';
document.body.append(a);
a.click();
a.remove();
window.URL.revokeObjectURL(url);
}
});
});
});
If there is a way in which this code can be properly written, I would appreciate the guidance! Like I have earlier said somewhere, am new to programming. I further need to refresh a certain element where am echoing the id value from my database after the ajax has run successfully so that the number of downloads is updated on link click.

Download sharepoint list attachment in IE browser [duplicate]

I have some big size PDF catalogs at my website, and I need to link these as download. When I googled, I found such a thing noted below. It should open the "Save As..." popup at link click...
<head>
<meta name="content-disposition" content="inline; filename=filename.pdf">
...
But it doesn't work :/ When I link to a file as below, it just links to file and is trying to open the file.
File name
UPDATE (according to answers below):
As I see there is no 100% reliable cross-browser solution for this. Probably the best way is using one of the web services listed below, and giving a download link...
http://box.net/
http://droplr.com/
http://getcloudapp.com/
From an answer to Force a browser to save file as after clicking link:
<a href="path/to/file" download>Click here to download</a>
Use the download attribute, but take into account that it only works for files hosted in the same origin that your code. It means that users can only download files that are from the origin site, same host.
Download with original filename:
Click here to download
Download with 'some_name' as filename:
Click here to download
Adding target="_blank" we will use a new Tab instead of the actual one, and also it will contribute to the proper behavior of the download attribute in some scenarios.
It follows the same rules as same-origin policy. You can learn more about this policy on the MDN Web Doc same-origin policy page
You can lern more about this download HTML5 attribute on the MDN Web Doc anchor's attributes page.
Meta tags are not a reliable way to achieve this result. Generally you shouldn't even do this - it should be left up to the user/user agent to decide what do to with the content you provide. The user can always force their browser to download the file if they wish to.
If you still want to force the browser to download the file, modify the HTTP headers directly. Here's a PHP code example:
$path = "path/to/file.pdf";
$filename = "file.pdf";
header('Content-Transfer-Encoding: binary'); // For Gecko browsers mainly
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($path)) . ' GMT');
header('Accept-Ranges: bytes'); // Allow support for download resume
header('Content-Length: ' . filesize($path)); // File size
header('Content-Encoding: none');
header('Content-Type: application/pdf'); // Change the mime type if the file is not PDF
header('Content-Disposition: attachment; filename=' . $filename); // Make the browser display the Save As dialog
readfile($path); // This is necessary in order to get it to actually download the file, otherwise it will be 0Kb
Note that this is just an extension to the HTTP protocol; some browsers might ignore it anyway.
I had this same issue and found a solution that has worked great so far. You put the following code in your .htaccess file:
<FilesMatch "\.(?i:pdf)$">
ForceType application/octet-stream
Header set Content-Disposition attachment
</FilesMatch>
It came from Force a File to Download Instead of Showing Up in the Browser.
I found a very simple solution for Firefox (only works with a relative rather than a direct href): add type="application/octet-stream":
Example
Generally it happens, because some browsers settings or plug-ins directly open PDF in the same window like a simple web page.
The following might help you. I have done it in PHP a few years back. But currently I'm not working on that platform.
<?php
if (isset($_GET['file'])) {
$file = $_GET['file'];
if (file_exists($file) && is_readable($file) && preg_match('/\.pdf$/',$file)) {
header('Content-type: application/pdf');
header("Content-Disposition: attachment; filename=\"$file\"");
readfile($file);
}
}
else {
header("HTTP/1.0 404 Not Found");
echo "<h1>Error 404: File Not Found: <br /><em>$file</em></h1>";
}
?>
Save the above as download.php.
Save this little snippet as a PHP file somewhere on your server and you can use it to make a file download in the browser, rather than display directly. If you want to serve files other than PDF, remove or edit line 5.
You can use it like so:
Add the following link to your HTML file.
Download the cool PDF.
Reference from: This blog
Try adding this line to your .htaccess file.
AddType application/octet-stream .pdf
I hope it'll work as it is browser independent.
I just used this, but I don't know if it works across all browsers.
It works in Firefox:
<a href="myfile.pdf" download>Click to Download</a>
A really simple way to achieve this, without using external download sites or modifying headers etc. is to simply create a ZIP file with the PDF inside and link directly to the ZIP file. This will ALWAYS trigger the Save/Open dialog, and it's still easy for people to double-click the PDF windows the program associated with .zip is launched.
BTW great question, I was looking for an answer as well, since most browser-embedded PDF plugins take sooo long to display anything (and will often hang the browser whilst the PDF is loading).
Just put the below code in your .htaccess file:
AddType application/octet-stream .csv
AddType application/octet-stream .xls
AddType application/octet-stream .doc
AddType application/octet-stream .avi
AddType application/octet-stream .mpg
AddType application/octet-stream .mov
AddType application/octet-stream .pdf
Or you can also do trick by JavaScript
element.setAttribute( 'download', whatever_string_you_want);
A very easy way to do this, if you need to force download for a single link on your page, is to use the HTML5 download-attribute in the href-link.
See: http://davidwalsh.name/download-attribute
with this you can rename the file that the user will download and at the same time it forces the download.
There has been a debate whether this is good practice or not, but in my case I have an embedded viewer for a PDF file and the viewer does not offer a download link, so i have to provide one separately. Here I want to make sure the user does not get the PDF opened in the web browser, which would be confusing.
This won't necessary open the save as-dialog, but will download the link straight to the preset download destination. And of course if you are doing a site for someone else, and need them to write in manually attributes to their links is probably a bad idea, but if there is way to get the attribute into the links, this can be a light solution.
A server-side solution is more compatible, until the "download" attribute is implemented in all the browsers.
One Python example could be a custom HTTP request handler for a filestore. The links that point to the filestore are generated like this:
http://www.myfilestore.com/filestore/13/130787e71/download_as/desiredName.pdf
Here is the code:
class HTTPFilestoreHandler(SimpleHTTPRequestHandler):
def __init__(self, fs_path, *args):
self.fs_path = fs_path # Filestore path
SimpleHTTPRequestHandler.__init__(self, *args)
def send_head(self):
# Overwrite SimpleHTTPRequestHandler.send_head to force download name
path = self.path
get_index = (path == '/')
self.log_message("path: %s" % path)
if '/download_as/' in path:
p_parts = path.split('/download_as/')
assert len(p_parts) == 2, 'Bad download link:' + path
path, download_as = p_parts
path = self.translate_path(path )
f = None
if os.path.isdir(path):
if not self.path.endswith('/'):
# Redirect browser - doing basically what Apache does
self.send_response(301)
self.send_header("Location", self.path + "/")
self.end_headers()
return None
else:
return self.list_directory(path)
ctype = self.guess_type(path)
try:
f = open(path, 'rb')
except IOError:
self.send_error(404, "File not found")
return None
self.send_response(200)
self.send_header("Content-type", ctype)
fs = os.fstat(f.fileno())
self.send_header("Expires", '0')
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.send_header("Cache-Control", 'must-revalidate, post-check=0, pre-check=0')
self.send_header("Content-Transfer-Encoding", 'binary')
if download_as:
self.send_header("Content-Disposition", 'attachment; filename="%s"' % download_as)
self.send_header("Content-Length", str(fs[6]))
self.send_header("Connection", 'close')
self.end_headers()
return f
class HTTPFilestoreServer:
def __init__(self, fs_path, server_address):
def handler(*args):
newHandler = HTTPFilestoreHandler(fs_path, *args)
newHandler.protocol_version = "HTTP/1.0"
self.server = BaseHTTPServer.HTTPServer(server_address, handler)
def serve_forever(self, *args):
self.server.serve_forever(*args)
def start_server(fs_path, ip_address, port):
server_address = (ip_address, port)
httpd = HTTPFilestoreServer(fs_path, server_address)
sa = httpd.server.socket.getsockname()
print "Serving HTTP on", sa[0], "port", sa[1], "..."
httpd.serve_forever()
This is old post but here is the one my solution in JavaScript what using jQuery library.
<script>
(function($){
var download = [];
$('a.force-download, .force-download a').each(function(){
// Collect info
var $this = $(this),
$href = $this.attr('href'),
$split = $href.split('/'),
$name = document.title.replace(/[\W_]/gi, '-').replace(/-{2,}/g, '-'); // get title and clean it for the URL
// Get filename from URL
if($split[($split.length-1)])
{
$tmp = $split[($split.length-1)];
$tmp = $tmp.split('.');
$name = $tmp[0].replace(/[\W_]/gi, '-').replace(/-{2,}/g, '-');
}
// If name already exists, put timestamp there
if($.inArray($name, download) > -1)
{
$name = $name + '-' + Date.now().replace(/[\W]/gi, '-');
}
$(this).attr("download", $name);
download.push($name);
});
}(jQuery || window.jQuery))
</script>
You just need to use class force-download inside your <a> tag and will force download automaticaly. You also can add it to parent div and will pickup all links inside it.
Example:
Download PDF
This is great for WordPress and any other systems or custom websites.
Add a response header Content-Disposition:attachment; followed by the file name. Remove the Meta Content-Disposition;Inline; which will open the document in the same window
In java it is set as
response.setHeader("Content-Disposition", "attachment;filename=test.jpg");
After the file name in the HTML code I add ?forcedownload=1
This has been the simplest way for me to trigger a dialog box to save or download.
If you have a plugin within the browser which knows how to open a PDF file it will open directly. Like in case of images and HTML content.
So the alternative approach is not to send your MIME type in the response. In this way the browser will never know which plugin should open it. Hence it will give you a Save/Open dialog box.
I just had a very similar issue with the added problem that I needed to create download links to files inside a ZIP file.
I first tried to create a temporary file, then provided a link to the temporary file, but I found that some browsers would just display the contents (a CSV Excel file) rather than offering to download. Eventually I found the solution by using a servlet. It works both on Tomcat and GlassFish, and I tried it on Internet Explorer 10 and Chrome.
The servlet takes as input a full path name to the ZIP file, and the name of the file inside the zip that should be downloaded.
Inside my JSP file I have a table displaying all the files inside the zip, with links that say: onclick='download?zip=<%=zip%>&csv=<%=csv%>'
The servlet code is in download.java:
package myServlet;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.zip.*;
import java.util.*;
// Extend HttpServlet class
public class download extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
PrintWriter out = response.getWriter(); // now we can write to the client
String filename = request.getParameter("csv");
String zipfile = request.getParameter("zip");
String aLine = "";
response.setContentType("application/x-download");
response.setHeader( "Content-Disposition", "attachment; filename=" + filename); // Force 'save-as'
ZipFile zip = new ZipFile(zipfile);
for (Enumeration e = zip.entries(); e.hasMoreElements();) {
ZipEntry entry = (ZipEntry) e.nextElement();
if(entry.toString().equals(filename)) {
InputStream is = zip.getInputStream(entry);
BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"), 65536);
while ((aLine = br.readLine()) != null) {
out.println(aLine);
}
is.close();
break;
}
}
}
}
To compile on Tomcat you need the classpath to include tomcat\lib\servlet-api.jar or on GlassFish: glassfish\lib\j2ee.jar
But either one will work on both. You also need to set your servlet in web.xml.
Chrome 91 had a new change, it supported in chrome 86-90 and 91+.
The following syntax will make it happen.
const fileHandle = await self.showSaveFilePicker({
suggestedName: 'Untitled Text.txt',
types: [{
description: 'Text documents',
accept: {
'text/plain': ['.txt'],
},
}],
});
Read more here:
https://developer.chrome.com/blog/new-in-chrome-91/
**Another solution you can just make it as a blob and then use saveAs **
const blob = fetch("some-url-here").then(data => data.blob());
saveAs(blob, "filename.txt")
With large PDF files the browser hangs.
In Mozilla, menu Tools → Options → Applications, then next to the content type Adobe Acrobat document.
In the Action drop down, select Always ask.
This did not work for me, so what worked was:
Menu Tools* → Add-ons → Adobe Acrobat (Adobe PDF plugin for Firefox) → DISABLE.
Now I am able to download e-books!

PHP Generating download link

Let's say i want to generate a download link and put it into <a> tag.
my php script:
function download_link(){
$this_id = "d"; //this is the name of file from server
$original_filename = 'xample.pdf'; //This come from database
$ext = pathinfo($original_filename, PATHINFO_EXTENSION);
$file = '../uploads/'.$this_id.'.'.$ext;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/'.$ext);
header('Content-Disposition: attachment; filename='.$original_filename);//Rename the file with its original filename
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
return readfile($file);//Here where i want to return the generated url
}
return '#'; //Or return nothing if file doesn't exist
echo ''; //And put it here, the generated url
now, my directory location is ../uploads/.
i am expecting a result like: so when the user click this tag the file will be downloaded. but instead, when i reload the page it is automatically downloading without clicking the download button which is the <a> tag.
note: i am trying to rename the filename when botton download is clicked.
i know there is a problem in my logic. maybe this can be done with JQUERY? or AJAX? im searching for solution but did not find the answer.
here's what i did with JQUERY AJAX:
HTML tag
<a id="server_name_file_name">download</a>
JQUERY AJAX:
$('a').click(function(e) {
e.preventDefault();
var id = $(this).attr('id');
$.ajax({
type: 'POST',
url: 'download.php',
data: { server_file_name: id,},
success: function(response) {
if(response == 1){
alert("Unable to download, Maybe the file is corrupted. Please try to reload the page.");
}else{
window.location.href = response;
return false;
}
}})
});
download.php
$this_id = $_POST['server_file_name'];
$original_filename = 'xample.pdf'; //This come from database
$ext = pathinfo($original_filename, PATHINFO_EXTENSION);
$file = '../uploads/'.$this_id.'.'.$ext;
if (file_exists($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/'.$ext);
header('Content-Disposition: attachment; filename='.$original_filename);//Rename the file with its original filename
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
echo readfile($file);//Here where i want to return the generated url
exit();
} die('1');
but doesnt work.
anyone can help me here? Thank you!!!!
You're returning the actual contents of the file with readfile.
Thats why browser starts to download the file you return.
What you need to do is to generate the string which will point to the file.
If your "uploads" dir is accessible by url, then your downloads.php should look like this:
$this_id = $_POST['server_file_name'];
$original_filename = 'xample.pdf'; //This come from database
$ext = pathinfo($original_filename, PATHINFO_EXTENSION);
$file = '../uploads/' . $this_id . '.' . $ext;
if (file_exists($file)) {
echo 'www.myserver.com/uploads/' . $this_id . '.' . $ext;
exit();
}
die('1');
If your uploads dir is not accessible from outside, then you need to copy the file into the public directory first.
At a first glance, i can identify a couple of problems.
Your download function does not return the link of the file but rather it outputs the file itself, so it is logical that when refreshing the page, the file is downloading.
Plus, I can see that you are calling your function useing function download_link() whereas it should be directly download_link().
The proper way this should be done is having the download link to a file executing the download_link function (ex: http://yoursite.com/download_file.php?file=filename)
Of course it is advisable to have an id instead of filename in the URL and apply all the security you need etc...
Inside download_file.php file, you can call download_link($filename) or better download_link($id) and get the file name from the database or wherever you are storing it and then output the file as you are doing now.

List files, read files as links, php?

This is a strange request I suppose, but I have a directory full of txt files. For example:
- david_smith_interview.txt -
- beth_martin_interview.txt -
- sally_smithart_interview.txt
The contents of these text files are a link to their interview in an mp3 format, for example, if you open the file david_smith_interview.txt, it is simply this:
http://www.interviews/employees/david_smith.mp3
All of the other text files follow the same format. They are simply links to their mp3 interview.
I am trying to use something like below to list the text files:
<?php
$directory = "/employees/";
$phpfiles = glob($directory . "*.txt");
foreach($phpfiles as $phpfile)
{
echo $phpfile; // This will list the files by name
// How can I output something to reflect this:
// david_smith_interview
}
?>
So I am asking is it possible that the text file can be "read" and used as the actual link?
Any thoughts?
Replace _interview.txt with .mp3
echo "" . str_replace(".txt", "", $phpfile). "\";
Since those are .txt files you can just read them one by one to a variable and then echo the result in a for-loop.
In pseudo:
$paths fetch_paths()
$urls = array();
foreach($paths as $path)
{
$url=fopen($path);
array_push($urls,fgets(url)); // Assuming there's only one link per file and it is on one line.
}
foreach($urls as $url)
{
echo <Your formatted link here>
}

How can I include all JavaScript files in a directory via JavaScript file?

I have a bunch of JavaScript files that I would like to include in the page, but I don't want to have to keep writing
<script type="text/javascript" src="js/file.js"></script>
So is there a way to include all files in a directory (unknown size)? Can I do something like...
$.getScript("js/*.js");
... to get all the JavaScript files in the "js" directory? How can I do this using jQuery?
In general, this is probably not a great idea, since your html file should only be loading JS files that they actually make use of. Regardless, this would be trivial to do with any server-side scripting language. Just insert the script tags before serving the pages to the client.
If you want to do it without using server-side scripting, you could drop your JS files into a directory that allows listing the directory contents, and then use XMLHttpRequest to read the contents of the directory, and parse out the file names and load them.
Option #3 is to have a "loader" JS file that uses getScript() to load all of the other files. Put that in a script tag in all of your html files, and then you just need to update the loader file whenever you upload a new script.
What about using a server-side script to generate the script tag lines? Crudely, something like this (PHP) -
$handle = opendir("scripts/");
while (($file = readdir($handle))!== false) {
echo '<script type="text/javascript" src="' . $file . '"></script>';
}
closedir($handle);
Given that you want a 100% client side solution, in theory you could probably do this:
Via XmlHttpRequest, get the directory listing page for that directory (most web servers return a listing of files if there is no index.html file in the directory).
Parse that file with javascript, pulling out all the .js files. This will of course be sensitive to the format of the directory listing on your web server / web host.
Add the script tags dynamically, with something like this:
function loadScript (dir, file) {
var scr = document.createElement("script");
scr.src = dir + file;
document.body.appendChild(scr);
}
It can be done fully client side, but all javascript file names must be specified.
For example, as array items:
function loadScripts(){
var directory = 'script/';
var extension = '.js';
var files = ['model', 'view', 'controller'];
for (var file of files){
var path = directory + file + extension;
var script = document.createElement("script");
script.src = path;
document.body.appendChild(script);
}
}
You can't do that in JavaScript, since JS is executed in the browser, not in the server, so it didn't know anything about directories or other server resources.
The best option is using a server side script like the one posted by jellyfishtree.
#jellyfishtree it would be a better if you create one php file which includes all your js files from the directory and then only include this php file via a script tag. This has a better performance because the browser has to do less requests to the server. See this:
javascripts.php:
<?php
//sets the content type to javascript
header('Content-type: text/javascript');
// includes all js files of the directory
foreach(glob("packages/*.js") as $file) {
readfile($file);
}
?>
index.php:
<script type="text/javascript" src="javascripts.php"></script>
That's it!
Have fun! :)
You could use something like Grunt Include Source. It gives you a nice syntax that preprocesses your HTML, and then includes whatever you want. This also means, if you set up your build tasks correctly, you can have all these includes in dev mode, but not in prod mode, which is pretty cool.
If you aren't using Grunt for your project, there's probably similar tools for Gulp, or other task runners.
You can't do that in Javascript from the browser... If I were you, I would use something like browserify. Write your code using commonjs modules and then compile the javascript file into one.
In your html load the javascript file that you compiled.
I was looking for an answer to this question and had my own problems. I found a couple solutions in various places and put them together into my own preferred answer.
function exploreFolder(folderURL,options){
/* options: type explaination
**REQUIRED** callback: FUNCTION function to be called on each file. passed the complete filepath
then: FUNCTION function to be called after loading all files in folder. passed the number of files loaded
recursive: BOOLEAN specifies wether or not to travel deep into folders
ignore: REGEX file names matching this regular expression will not be operated on
accept: REGEX if this is present it overrides the `ignore` and only accepts files matching the regex
*/
$.ajax({
url: folderURL,
success: function(data){
var filesLoaded = 0,
fileName = '';
$(data).find("td > a").each(function(){
fileName = $(this).attr("href");
if(fileName === '/')
return; //to account for the (go up a level) link
if(/\/\//.test(folderURL + fileName))
return; //if the url has two consecutive slashes '//'
if(options.accept){
if(!options.accept.test(fileName))
//if accept is present and the href fails, dont callback
return;
}else if(options.ignore)
if(options.ignore.test(fileName))
//if ignore is present and the href passes, dont callback
return;
if(fileName.length > 1 && fileName.substr(fileName.length-1) === "/")
if(options.recursive)
//only recurse if we are told to
exploreFolder(folderURL + fileName, options);
else
return;
filesLoaded++;
options.callback(folderURL + fileName);
//pass the full URL into the callback function
});
if(options.then && filesLoaded > 0) options.then(filesLoaded);
}
});
}
Then you can call it like this:
var loadingConfig = {
callback: function(file) { console.log("Loaded file: " + file); },
then: function(numFiles) { console.log("Finished loading " + numFiles + " files"); },
recursive: true,
ignore: /^NOLOAD/,
};
exploreFolder('/someFolderURL/', loadingConfig);
This example will call that callback on every file/folder in the specified folder except for ones that start with NOLOAD. If you want to actually load the file into the page then you can use this other helper function that I developed.
function getFileExtension(fname){
if(fname)
return fname.substr((~-fname.lastIndexOf(".") >>> 0) + 2);
console.warn("No file name provided");
}
var loadFile = (function(filename){
var img = new Image();
return function(){
var fileref,
filename = arguments[0],
filetype = getFileExtension(filename).toLowerCase();
switch (filetype) {
case '':
return;
case 'js':
fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src", filename);
break;
case "css":
fileref=document.createElement("link");
fileref.setAttribute("rel", "stylesheet");
fileref.setAttribute("type", "text/css");
fileref.setAttribute("href", filename);
break;
case "jpg":
case "jpeg":
case 'png':
case 'gif':
img.src = filename;
break;
default:
console.warn("This file type is not supported: "+filetype);
return;
}
if (typeof fileref !== undefined){
$("head").append(fileref);
console.log('Loaded file: ' + filename);
}
}
})();
This function accepts a JS | CSS | (common image) file and loads it. It will also execute the JS files.
The complete call that needs to be run in your script to load all images and* stylesheets and other scripts could look like this:
loadingConfig = {
callback: loadfile,
then: function(numFiles) { console.log("Finished loading " + numFiles + " files"); },
recursive: true,
ignore: /^NOLOAD/,
};
exploreFolder('/someFolderURL/', loadingConfig);
It works amazingly!
Another option that is pretty short:
<script type="text/javascript">
$.ajax({
url: "/js/partials",
success: function(data){
$(data).find('a:contains(.js)').each(function(){
// will loop through
var partial= $(this).attr("href");
$.getScript( "/js/partials/" + partial, function( data, textStatus, jqxhr ) {});
});
}
});
</script>

Categories

Resources