繁体   English   中英

js function 从 url 获取文件名

[英]js function to get filename from url

我有一个 url 像http://www.example.com/blah/th.html

我需要一个 javascript function 来给我'th'值。

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

我希望它是一个安全的 function,所以如果有人通过一个空的 url 它不会损坏。

我知道如何检查长度,但我应该检查 null 对吗?

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

为什么这么难?

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

使用匹配功能。

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

与其他人相似,但是......我使用了汤姆的简单脚本 - 一行,
那么你可以在任何地方使用文件名 var:
http://www.tomhoppe.com/index.php/2008/02/grab-filename-from-window-location/

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

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

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

JSFiddle在这里

这应该适用于所有情况

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

这些不适用于长网址,例如
“/my/folder/questions.html#dssddsdsd?toto=33&dududu=podpodpo”

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

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

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

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)

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

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

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');
}

这里有两个函数:

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

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

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

  • 某些操作系统不允许文件名中的某些字符(例如:在 Windows 中,在大多数操作系统中为\\0 ,...);
  • 某些文件名可能由操作系统保留(例如 Windows 中的CON );
  • 有些文件名可能使用户不快来处理它(如一个文件名为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')

我会使用substring函数与lastIndexOf结合使用。 这将允许包含句点的文件名,例如给定http://example.com/file.name.txt这给出了file.name不像接受的答案会给出file

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

因为自定义代码的案例往往会失败,所以我查找了 JavaScript URL类。 唉,它在相对 URL 上窒息! 此外,它没有获取文件名的属性。 不是史诗。

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

let file = new URI(url).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
}

这是一个带有测试用例的片段。 除驱动路径外,所有情况都通过。

 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>

结果

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
  =>  ""

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

使用 jQuery 和URL 插件

var file = jQuery.url.attr("file");
var fileNoExt = file.replace(/\.(html|htm)$/, "");
// file == "th.html", fileNoExt = "th"
<script type="text/javascript">
function getFileName(url){
  var path = window.location.pathName;
  var file = path.replace(/^.*\/(\w{2})\.html$/i, "$1");
  return file ? file : "undefined";
}
</script>

对于节点和浏览器,基于@pauls 的回答,但解决了散列和更具防御性的问题:

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

少数情况:

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')
  })
})

基于 TypeScript 的 ES6 语法

实际上,标记的答案是正确的,但是如果第二个if不满足函数返回undefined ,我更喜欢像下面这样写:

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

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

  return '';
};

对于我的问题,我需要文件扩展名。

这应该可以处理您抛出的任何内容(绝对 URL、相对 URL、复杂的 AWS URL 等)。 如果文件名和默认值都不存在,它包括一个可选的默认值或使用伪随机字符串。

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;
}

@hayatbiralem 的道具,用于确定split()的顺序

与@user2492653 建议的类似,如果你想要的只是像 Firefox 给你的文件名,那么你可以使用 split() 方法,它将字符串分解成一个组件数组,然后你需要做的就是抓住最后一个指数。

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

这基本上会将 C:/fakepath/test.csv 分解为 {"C:", "fakepath", "test.csv"}

我的 2 美分

如果查询字符串包含“/”,LastIndexOf("/") 方法本身就会失效

我们都知道它们“应该”被编码为%2F但只需要一个未转义的值就会引起问题。

此版本正确处理查询字符串中的 / 并且不依赖于 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);
}

尝试这个

url.substring(url.lastIndexOf('/')+1, url.length)
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(/\.[^.]+$/, '');
}

这将从这个 URL http://www.myblog.com/news.php?year=2019#06返回news

url? url.substring(url.lastIndexOf('/')+1, url.lastIndexOf('.')):''
  • 安全是要求的。 当 url 为nullundefined ,结果为''
  • 删除所有带有“:”、点和任何符号(包括最后一个“/”)的路径。
  • 这给出了真正的答案'th'而不是'th.index' 当然,让它发挥作用是非常重要的。
  • 它允许文件名有几个句点!

  • 未询问,但您也可以使用不带“/”和“.”的查询字符串。

这是 Abhishek Sharma 的正确答案,所以我给了他一个赞成票。 如此巧妙和最小的单线 - 我在那里看到了:)

除了现有的答案之外,我还建议使用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}`);

简单函数(使用 RegEx 模式)

 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);

使用正则表达式

假设你有这个 url:

http://127.0.0.1:3000/pages/blog/posts/1660345251.html

使用以下代码行:

var filename = location.pathname.replace(/[\D]/g, "");

将返回:

1660345251
  • 请注意,这个数字是Unix Time ,无论您在世界的哪个地方,它都会返回您的本地时间(这应该为您提供此博客示例的真正唯一的帖子名称)。
  • .replace(/[\D]/g, "") ,用空字符串替换任何非数字字符。 /[\D]/g表示非数字, ""表示空字符串。 更多信息: 这里是数字这里是字母
  • 有关 RegEx 的更多信息,请点击此处 有很多 RegEx 工具可以帮助您在filename的返回值中获得更好的结果。

额外代码:Unix 时间到本地时间

var humanDate = new Date(0);
var timestamp = entries[index].timestamp;
humanDate.setUTCSeconds(timestamp);

humanDate是我的当地时间:

Fri Aug 12 2022 20:00:51 GMT-0300 (Argentina Standard Time)

此代码的学分, here

如何使用 JavaScript 从完整路径获取文件名?

var filename = fullPath.replace(/^.*[\\\/]/, '')

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM