js function to get filename from url

JavascriptFunction

Javascript Problem Overview


I have a url like http://www.example.com/blah/th.html

I need a javascript function to give me the 'th' value from that.

All my urls have the same format (2 letter filenames, with .html extension).

I want it to be a safe function, so if someone passes in an empty url it doesn't break.

I know how to check for length, but I should be checking for null to right?

Javascript Solutions


Solution 1 - Javascript

var filename = url.split('/').pop()

Solution 2 - Javascript

Why so difficult?

var filename = url.split('/').pop().split('#')[0].split('?')[0];

Solution 3 - Javascript

Use the match function.

function GetFilename(url)
{
   if (url)
   {
      var m = url.toString().match(/.*\/(.+?)\./);
      if (m && m.length > 1)
      {
         return m[1];
      }
   }
   return "";
}

Solution 4 - Javascript

Similar to the others, but...I've used Tom's simple script - a single line,
then you can use the filename var anywhere:
http://www.tomhoppe.com/index.php/2008/02/grab-filename-from-window-location/

var filename = location.pathname.substr(location.pathname.lastIndexOf("/")+1);

Solution 5 - Javascript

A regex solution which accounts for URL query and hash identifier:

function fileNameFromUrl(url) {
   var matches = url.match(/\/([^\/?#]+)[^\/]*$/);
   if (matches.length > 1) {
     return matches[1];
   }
   return null;
}

JSFiddle here.

Solution 6 - Javascript

This should work for all cases

function getFilenameFromUrl(url) {
  const pathname = new URL(url).pathname;
  const index = pathname.lastIndexOf('/');
  return (-1 !== index) ? pathname.substring(index + 1) : pathname;
}

Solution 7 - Javascript

Because cases tend to fail with custom code, I looked up to the JavaScript URL class. Alas, it chokes on relative URLs! Also, it doesn't have a property to get the file name. Not epic.

There has to be a good library out there which solves this common problem. Behold URI.js. All you need is a simple statement like the following:

let file = new URI(url).filename()

Then we can create a simple function that does null checks and removes the file extension:

function fileName(url) {
   if (url === null || typeof url === 'undefined')
      return ''
   let file = new URI(url).filename() // File name with file extension
   return file.substring(0, file.lastIndexOf('.')) // Remove the extension
}

Here's a snippet with test cases to play around with. All cases pass except drive paths.

test('Dots in file name without URL', 'dotted.file.name.png', 'dotted.file.name')
test('Dots in file name with URL', 'http://example.com/file.name.txt', 'file.name')
test('Lengthy URL with parameters', '/my/folder/filename.html#dssddsdsd?toto=33&dududu=podpodpo', 'filename')
test('URL with hash', '/my/folder/filename.html#dssddsdsd', 'filename')
test('URL with query strings', '/my/folder/filename.html?toto=33&dududu=podpodp', 'filename')
test('Hash after query string', 'http://www.myblog.com/filename.php?year=2019#06', 'filename')
 test('Query parameter with file path character', 'http://www.example.com/filename.zip?passkey=1/2', 'filename')
test('Query parameter with file path character and hash', 'http://www.example.com/filename.html?lang=en&user=Aan9u/o8ai#top', 'filename')
test('Asian characters', 'http://example.com/文件名.html', '文件名')
test('URL without file name', 'http://www.example.com', '')
test('Null', null, '')
test('Undefined', undefined, '')
test('Empty string', '', '')
test('Drive path name', 'C:/fakepath/filename.csv', 'filename')

function fileName(url) {
   if (url === null || typeof url === 'undefined')
      return ''
   let file = new URI(url).filename() // File name with file extension
   return file.substring(0, file.lastIndexOf('.')) // Remove the extension
}

function test(description, input, expected) {
   let result = fileName(input)
   let pass = 'FAIL'
   if (result === expected)
      pass = 'PASS'
   console.log(pass + ': ' + description + ': ' + input)
   console.log('  =>  "' + fileName(input) + '"')
}

<script src="https://cdn.jsdelivr.net/gh/medialize/URI.js@master/src/URI.js"></script>

Results

PASS: Dots in file name without URL: dotted.file.name.png
  =>  "dotted.file.name"
PASS: Dots in file name with URL: http://example.com/file.name.txt
  =>  "file.name"
PASS: Lengthy URL with parameters: /my/folder/filename.html#dssddsdsd?toto=33&dududu=podpodpo
  =>  "filename"
PASS: URL with hash: /my/folder/filename.html#dssddsdsd
  =>  "filename"
PASS: URL with query strings: /my/folder/filename.html?toto=33&dududu=podpodp
  =>  "filename"
PASS: Hash after query string: http://www.myblog.com/filename.php?year=2019#06
  =>  "filename"
PASS: Query parameter with file path character: http://www.example.com/filename.zip?passkey=1/2
  =>  "filename"
PASS: Query parameter with file path character and hash: http://www.example.com/filename.html?lang=en&user=Aan9u/o8ai#top
  =>  "filename"
PASS: Asian characters: http://example.com/文件名.html
  =>  "文件名"
PASS: URL without file name: http://www.example.com
  =>  ""
PASS: Null: null
  =>  ""
PASS: Undefined: undefined
  =>  ""
PASS: Empty string: 
  =>  ""
FAIL: Drive path name: C:/fakepath/filename.csv
  =>  ""

This solution is for you if you're too lazy to write custom code and don't mind using a library to do work for you. It isn't for you if you want to code golf the solution.

Solution 8 - Javascript

In addition to the existing answers, I would recommend using URL() constructor (works both in browsers and Node.js) because you can be sure your URL is valid:

const url = 'https://test.com/path/photo123.png?param1=1&param2=2#hash';

let filename = '';
try {
  filename = new URL(url).pathname.split('/').pop();
} catch (e) {
  console.error(e);
}
console.log(`filename: ${filename}`);

Solution 9 - Javascript

those will not work for lenghty url like
"/my/folder/questions.html#dssddsdsd?toto=33&dududu=podpodpo"

here I expect to get "questions.html". So a possible (slow) solution is as below

fname=function(url) 
{ return url?url.split('/').pop().split('#').shift().split('?').shift():null }

then you can test that in any case you get only the filename.

fname("/my/folder/questions.html#dssddsdsd?toto=33&dududu=podpodpo")
-->"questions.html"
fname("/my/folder/questions.html#dssddsdsd")
-->"questions.html"
fname("/my/folder/questions.html?toto=33&dududu=podpodpo")
"-->questions.html"

(and it works for null)

(I would love to see a faster or smarter solution)

Solution 10 - Javascript

This answer only works in browser environment. Not suitable for node.

function getFilename(url) {
  const filename = decodeURIComponent(new URL(url).pathname.split('/').pop());
  if (!filename) return 'index.html'; // some default filename
  return filename;
}

function filenameWithoutExtension(filename) {
  return filename.replace(/^(.+?)(?:\.[^.]*)?$/, '$1');
}

Here are two functions:

  • first one get filename from url
  • second one get filename without extension from a full filename

For parsing URL, new an URL object should be the best choice. Also notice that URL do not always contain a filename.

Notice: This function try to resolve filename from an URL. But it do NOT guarantee that the filename is valid and suitable for use:

  • Some OS disallow certain character in filename (e.g. : in windows, \0 in most OS, ...);
  • Some filename may reserved by OS (e.g. CON in windows);
  • Some filename may make user unhappy to handle it (e.g. a file named "--help" in Linux)

Test it out:

function getFilename(url) {
  const filename = decodeURIComponent(new URL(url).pathname.split('/').pop());
  if (!filename) return 'index.html'; // some default filename
  return filename;
}

function test(url) {
  console.log('Filename: %o\nUrl: %o', getFilename(url), url);
}

test('http://www.example.com');
test('http://www.example.com/');
test('http://www.example.com/name.txt');
test('http://www.example.com/path/name.txt');
test('http://www.example.com/path/name.txt/realname.txt');
test('http://www.example.com/page.html#!/home');
test('http://www.example.com/page.html?lang=en&user=Aan9u/o8ai#top');
test('http://www.example.com/%E6%96%87%E4%BB%B6%E5%90%8D.txt')

Solution 11 - Javascript

I'd use the substring function combined with lastIndexOf. This will allow for filenames with periods in them e.g. given http://example.com/file.name.txt this gives file.name unlike the accepted answer that would give file.

function GetFilename(url)
{
    if (url)
    {
        return url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));
    }
    return "";
}

Solution 12 - Javascript

Using jQuery with the URL plugin:

var file = jQuery.url.attr("file");
var fileNoExt = file.replace(/\.(html|htm)$/, "");
// file == "th.html", fileNoExt = "th"

Solution 13 - Javascript

For node and browsers, based on @pauls answer but solving issues with hash and more defensive:

export function getFileNameFromUrl(url) {
  const hashIndex = url.indexOf('#')
  url = hashIndex !== -1 ? url.substring(0, hashIndex) : url
  return (url.split('/').pop() || '').replace(/[\?].*$/g, '')
} 

Few cases:

describe('getFileNameFromUrl', () => {

  it('absolute, hash and no extension', () => {
    expect(getFileNameFromUrl(
      'https://foo.bar/qs/bar/js-function-to-get-filename-from-url#comment95124061_53560218'))
    .toBe('js-function-to-get-filename-from-url')
  })

  it('relative, extension and parameters', () => {
    expect(getFileNameFromUrl('../foo.png?ar=8')).toBe('foo.png')
  })

  it('file name with multiple dots, hash with slash', () => {
    expect(getFileNameFromUrl('questions/511761/js-function.min.js?bar=9.9&y=1#/src/jjj?=9.9')).toBe('js-function.min.js')
  })
})

Solution 14 - Javascript

This should handle anything you throw at it (absolute URLs, relative URLs, complex AWS URLs, etc). It includes an optional default or uses a psuedorandom string if neither a filename nor a default were present.

function parseUrlFilename(url, defaultFilename = null) {
	let filename = new URL(url, "https://example.com").href.split("#").shift().split("?").shift().split("/").pop(); //No need to change "https://example.com"; it's only present to allow for processing relative URLs.
	if(!filename) {
		if(defaultFilename) {
			filename = defaultFilename;
		//No default filename provided; use a pseudorandom string.
		} else {
			filename = Math.random().toString(36).substr(2, 10);
		}
	}
	
	return filename;
}

Props to @hayatbiralem for nailing the order of the split()s.

Solution 15 - Javascript

Similarly to what @user2492653 suggested, if all you want is the name of the file like Firefox gives you, then you the split() method, which breaks the string into an array of components, then all you need to do it grab the last index.

var temp = url.split("//");
if(temp.length > 1)
 return temp[temp.length-1] //length-1 since array indexes start at 0

This would basically break C:/fakepath/test.csv into {"C:", "fakepath", "test.csv"}

Solution 16 - Javascript

my 2 cents

the LastIndexOf("/") method in itself falls down if the querystrings contain "/"

We all know they "should" be encoded as %2F but it would only take one un-escaped value to cause problems.

This version correctly handles /'s in the querystrings and has no reliance on .'s in the url

function getPageName() {
    //#### Grab the url
    var FullUrl = window.location.href;

    //#### Remove QueryStrings
    var UrlSegments = FullUrl.split("?")
    FullUrl = UrlSegments[0];

    //#### Extract the filename
    return FullUrl.substr(FullUrl.lastIndexOf("/") + 1);
}

Solution 17 - Javascript

Try this

url.substring(url.lastIndexOf('/')+1, url.length)

Solution 18 - Javascript

function getFileNameWithoutExtension(url) {
  if (typeof url !== 'string') throw new Error('url must be a string');
  // Remove the QueryString
  return url.replace(/\?.*$/, '')
  // Extract the filename
  .split('/').pop()
  // Remove the extension
  .replace(/\.[^.]+$/, '');
}

This will return news from this URL http://www.myblog.com/news.php?year=2019#06.

Solution 19 - Javascript

url? url.substring(url.lastIndexOf('/')+1, url.lastIndexOf('.')):''
  • Safety is as asked for. when url is null or undefined the result is ''.

  • Removes all of the path with ':', dots and any symbol including the last '/'.

  • This gives the true answer 'th' as asked and not 'th.index'. That is very important of course to have it work at all.

  • It allows filename to have several periods!

  • Not asked, but you can also have a query string without '/' and '.'

It is a corrected answer from Abhishek Sharma so I gave him an upvote. So genious and minimal one-liner - I saw it there :)

Solution 20 - Javascript

ES6 syntax based on TypeScript

Actually, the marked answer is true but if the second if doesn't satisfy the function returns undefined, I prefer to write it like below:

const getFileNameFromUrl = (url: string): string => {
  if (url) {
    const tmp = url.split('/');
    const tmpLength = tmp.length;

    return tmpLength ? tmp[tmpLength - 1] : '';
  }

  return '';
};

For my problem, I need to have the file extension.

Solution 21 - Javascript

Simple Function (Using RegEx Pattern)

function pathInfo(s) {
    s=s.match(/(.*?\/)?(([^/]*?)(\.[^/.]+?)?)(?:[?#].*)?$/);
    return {path:s[1],file:s[2],name:s[3],ext:s[4]};
}

var sample='/folder/another/file.min.js?query=1';
var result=pathInfo(sample);
console.log(result);
/*
{
  "path": "/folder/another/",
  "file": "file.min.js",
  "name": "file.min",
  "ext": ".js"
}
*/
console.log(result.name);

Solution 22 - Javascript

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBlankmanView Question on Stackoverflow
Solution 1 - Javascriptuser2492653View Answer on Stackoverflow
Solution 2 - JavascriptQuidnView Answer on Stackoverflow
Solution 3 - JavascriptDavid MortonView Answer on Stackoverflow
Solution 4 - JavascriptbrandonjpView Answer on Stackoverflow
Solution 5 - JavascriptBenjineerView Answer on Stackoverflow
Solution 6 - JavascriptVictorView Answer on Stackoverflow
Solution 7 - JavascriptDenis G. LabrecqueView Answer on Stackoverflow
Solution 8 - JavascriptsergdenisovView Answer on Stackoverflow
Solution 9 - JavascriptNadirView Answer on Stackoverflow
Solution 10 - JavascripttshView Answer on Stackoverflow
Solution 11 - JavascriptJamesView Answer on Stackoverflow
Solution 12 - JavascriptChase SeibertView Answer on Stackoverflow
Solution 13 - JavascriptcancerberoView Answer on Stackoverflow
Solution 14 - JavascriptrinogoView Answer on Stackoverflow
Solution 15 - Javascriptadam5990View Answer on Stackoverflow
Solution 16 - JavascriptHeavenCoreView Answer on Stackoverflow
Solution 17 - JavascriptAbhishek SharmaView Answer on Stackoverflow
Solution 18 - JavascriptKarl.SView Answer on Stackoverflow
Solution 19 - Javascriptuser985399View Answer on Stackoverflow
Solution 20 - JavascriptAmerllicAView Answer on Stackoverflow
Solution 21 - JavascriptMMMahdy-PAPIONView Answer on Stackoverflow
Solution 22 - JavascripttnusraddinovView Answer on Stackoverflow