js函数从url获取文件名

Bla*_*man 42 javascript function

我有一个像http://www.example.com/blah/th.html这样的网址

我需要一个javascript函数来给我'th'值.

我的所有网址都有相同的格式(2个字母的文件名,扩展名为.html).

我希望它是一个安全的功能,所以如果有人传入一个空的URL它不会破坏.

我知道如何检查长度,但我应该检查null是否正确?

小智 120

var filename = url.split('/').pop()
Run Code Online (Sandbox Code Playgroud)

  • 如果后面有查询参数怎么办? (8认同)
  • 怎么样:url.split('#').shift().split('?').shift().split('/').pop() (8认同)
  • 到目前为止最简单和最好的答案. (7认同)
  • @hayatbiralem你的回答是正确的:你必须先从清洁#和?开始 然后拆分/或者你将得到/ in querystring和anchors (3认同)
  • 尽管所有赞成票都不正确!错过了很多点.. 不检查 url 是否未定义......不会在 '.' 上拆分 ... 不删除最终查询字符串 ... (3认同)
  • 即使假设没有查询字符串、路径、片段等,这不会产生 'th.html' 而不是 'th',这是请求者所要求的吗? (3认同)
  • 这个怎么样?`new URL(url).pathname.split('/').pop();` (3认同)
  • 这也不处理URL片段ID(即#ID) (2认同)
  • 它几乎是正确的,但不适用于 `http://domain/THE_PATH?firstParam=BLABLA/BLEBLE".split('/').pop()` (2认同)

Qui*_*idn 60

为什么这么难?

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

  • @hayatbiralem给出了另一个评论的更好答案:url.split('#').shift().split('?').shift().split('/').pop()你必须从分裂开始在#和?然后拆分/或者您将捕获锚点和查询字符串的/部分而不是路径中的部分(这通常会导致亚马逊s3受保护网址上的错误) (6认同)
  • 如果 URL 实际上没有文件名怎么办?例如:`http://www.example.com` 此函数将返回不正确的“www.example.com”。它应该是空字符串或 null。 (3认同)
  • 这应该是最佳答案。 (2认同)
  • 不适用于“http://www.example.com/filenam.zip?passkey=1/2”` (2认同)

Dav*_*ton 21

使用匹配功能.

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

  • 如果文件名中有多个'.',则不起作用 (13认同)
  • 这将返回不带扩展名的文件名。 (2认同)

Ser*_*sov 15

除了现有的答案之外,我建议使用URL() constructor(在浏览器和 Node.js 中均有效),因为您可以确保您的 URL 有效:

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}`);
Run Code Online (Sandbox Code Playgroud)

  • 使用新的内置 Array 方法,我们可以执行 `new URL(url).pathname.split('/').at(-1)`。`.pop()` 仍然有效。 (2认同)

bra*_*njp 10

与其他人类似,但是......我使用过汤姆的简单脚本 - 一行,
然后你可以在任何地方使用文件名var:http:
//www.tomhoppe.com/index.php/2008/02/grab-文件名从-窗口的位置/

var filename = location.pathname.substr(location.pathname.lastIndexOf("/")+1);
Run Code Online (Sandbox Code Playgroud)


Vic*_*tor 6

这应该适用于所有情况

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


Den*_*que 6

由于使用自定义代码的案例往往会失败,因此我参考了 JavaScriptURL类。唉,它被相对 URL 噎住了!此外,它没有获取文件名的属性。不是史诗。

\n

必须一个好的库来解决这个常见问题。看 URI.js。您所需要的只是一个简单的语句,如下所示:

\n
let file = new URI(url).filename()\n
Run Code Online (Sandbox Code Playgroud)\n

然后我们可以创建一个简单的函数来执行 null 检查并删除文件扩展名:

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

这是一个包含测试用例的片段供您使用。除驱动器路径外,所有情况均通过。

\n

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

\n

结果

\n
PASS: Dots in file name without URL: dotted.file.name.png\n  =>  "dotted.file.name"\nPASS: Dots in file name with URL: http://example.com/file.name.txt\n  =>  "file.name"\nPASS: Lengthy URL with parameters: /my/folder/filename.html#dssddsdsd?toto=33&dududu=podpodpo\n  =>  "filename"\nPASS: URL with hash: /my/folder/filename.html#dssddsdsd\n  =>  "filename"\nPASS: URL with query strings: /my/folder/filename.html?toto=33&dududu=podpodp\n  =>  "filename"\nPASS: Hash after query string: http://www.myblog.com/filename.php?year=2019#06\n  =>  "filename"\nPASS: Query parameter with file path character: http://www.example.com/filename.zip?passkey=1/2\n  =>  "filename"\nPASS: Query parameter with file path character and hash: http://www.example.com/filename.html?lang=en&user=Aan9u/o8ai#top\n  =>  "filename"\nPASS: Asian characters: http://example.com/\xe6\x96\x87\xe4\xbb\xb6\xe5\x90\x8d.html\n  =>  "\xe6\x96\x87\xe4\xbb\xb6\xe5\x90\x8d"\nPASS: URL without file name: http://www.example.com\n  =>  ""\nPASS: Null: null\n  =>  ""\nPASS: Undefined: undefined\n  =>  ""\nPASS: Empty string: \n  =>  ""\nFAIL: Drive path name: C:/fakepath/filename.csv\n  =>  ""\n
Run Code Online (Sandbox Code Playgroud)\n

如果您懒得编写自定义代码并且不介意使用库来为您工作,那么此解决方案适合您。如果您想编写解决方案的代码,那么它不适合您。

\n


Nad*_*dir 5

这些不适用于像“/my/folder/questions.html#dssddsdsd?toto=33&dududu=podpodpo”这样的网址

在这里我希望得到“questions.html”。所以一个可能的(慢)解决方案如下

fname=function(url) 
{ return url?url.split('/').pop().split('#').shift().split('?').shift():null }
Run Code Online (Sandbox Code Playgroud)

然后你可以测试在任何情况下你都只得到文件名。

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)
Run Code Online (Sandbox Code Playgroud)

(我很想看到更快或更智能的解决方案)

  • 请参阅有问题的第二行:我需要一个 javascript 函数来从中获取 'th' 值。 (2认同)

Ben*_*eer 5

考虑URL查询和哈希标识符的正则表达式解决方案:

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

JSFiddle 在这里.


tsh*_*tsh 5

该答案仅适用于浏览器环境。不适合节点。

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');
}
Run Code Online (Sandbox Code Playgroud)

这里有两个函数:

  • 第一个从 url 获取文件名
  • 第二个从完整文件名中获取不带扩展名的文件名

对于解析URL,new一个URL对象应该是最好的选择。另请注意,URL 并不总是包含文件名。

注意:此函数尝试从 URL 解析文件名。但它不保证文件名有效且适合使用:

  • 某些操作系统不允许文件名中包含某些字符(例如,:在 Windows 中,\0在大多数操作系统中,...);
  • 某些文件名可能由操作系统保留(例如CON在Windows中);
  • 某些文件名可能会让用户不愿意处理它(例如,Linux 中名为“--help”的文件)

测试一下:

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')
Run Code Online (Sandbox Code Playgroud)

  • @PauliSudarshanTerho 但答案应该首先是正确的,然后是简单的。我看不出简单 = 安全是如何成立的。 (2认同)