【问题标题】:javascript/jquery add trailing slash to url (if not present)javascript/jquery 向 url 添加斜杠(如果不存在)
【发布时间】:2012-07-16 21:32:39
【问题描述】:

我正在制作一个小型 Web 应用程序,用户在其中输入一个服务器 URL,它通过 AJAX 请求从中提取大量数据。

由于用户必须手动输入 URL,人们通常会忘记尾部斜杠,即使它是必需的(因为某些数据会附加到输入的 url)。我需要一种方法来检查斜线是否存在,如果不存在,请添加它。

这似乎是一个 jQuery 可以解决的问题,有谁知道如何做到这一点,或者我应该为它编写一个 JS 函数吗?

【问题讨论】:

  • if(yourString.charAt(yourString.length-1) != '/'){yourString+='/'}
  • ...认真的。只需自己编写代码。你花更多的时间问这个问题,你会花更多的时间来写代码。
  • @TheZ substr 也想要你的爱......
  • @c69 是的,但是我并没有从我的曲目中获得另一条 jQ 行的好处;)
  • @c69 嗯,yourString[yourString.length-1] 显然是最快的。 charAt 是第二快的。 substr 因为这是最慢的方法,因为它没有将字符串作为数组访问。

标签: javascript jquery validation


【解决方案1】:
var lastChar = url.substr(-1); // Selects the last character
if (lastChar != '/') {         // If the last character is not a slash
   url = url + '/';            // Append a slash to it.
}

临时变量名可以省略,直接嵌入到断言中:

if (url.substr(-1) != '/') url += '/';

由于目标是用单行更改url,所以也可以使用以下解决方案:

url = url.replace(/\/?$/, '/');
  • 如果尾部斜杠存在,则替换为/
  • 如果尾部斜杠不存在,则在末尾附加一个/(准确地说:尾部锚点替换为/)。

【讨论】:

    【解决方案2】:
    url += url.endsWith("/") ? "" : "/"
    

    【讨论】:

    • 我更喜欢这个,因为它不使用(昂贵的)正则表达式。
    • 这个更漂亮简洁了
    • @A.Rabus 你能详细说明为什么使用正则表达式很贵吗?我猜你指的是性能,但不确定为什么这个解决方案在这方面更好?本机 .endsWith() 是如何工作的?提前致谢。
    • 正则表达式是复杂的小模式匹配程序,endswith 只是寻找最后一个字符...
    【解决方案3】:

    我添加到正则表达式解决方案以适应查询字符串:

    http://jsfiddle.net/hRheW/8/

    url.replace(/\/?(\?|#|$)/, '/$1')
    

    【讨论】:

    • 好的正则表达式——仅供参考,你的小提琴缺少对“#”的检查,(尽管你的答案显然有。)
    • 不错的正则表达式!可以通过将 '/$1' 更改为 '$1' 轻松转换为删除斜杠,这正是我正在寻找的 :)
    【解决方案4】:

    这也有效:

    url = url.replace(/\/$|$/, '/');
    

    例子:

    let urlWithoutSlash = 'https://www.example.com/path';
    urlWithoutSlash = urlWithoutSlash.replace(/\/$|$/, '/');
    console.log(urlWithoutSlash);
    
    let urlWithSlash = 'https://www.example.com/path/';
    urlWithSlash = urlWithSlash.replace(/\/$|$/, '/');
    console.log(urlWithSlash);
    

    输出:

    https://www.example.com/path/
    https://www.example.com/path/
    

    它用尾部斜杠替换尾部斜杠或没有尾部斜杠。因此,如果存在斜线,则将其替换为一个(基本上将其留在那里);如果不存在,则添加尾部斜杠。

    【讨论】:

    • @BilalHussain 与'/$|$' 基本相同,'\' 只是转义了后面的斜杠('/')。 '$' 表示检查输入字符串的结尾,'|' 只是一个OR。所以,用文字来说:匹配字符串末尾的/ 匹配字符串的末尾并将其替换为/。请参阅here 了解更多信息。
    • 最优雅的做法,我不明白为什么这个没有最多票
    【解决方案5】:

    你可以这样做:

    var url = 'http://stackoverflow.com';
    
    if (!url.match(/\/$/)) {
        url += '/';
    }
    

    这是证据:http://jsfiddle.net/matthewbj/FyLnH/

    【讨论】:

    • 如果你想避免正则表达式:if (url.slice(-1) !== '/') {
    【解决方案6】:

    URL 类非常棒 - 它可以帮助我们更改路径并处理查询参数和片段标识符

    function addTrailingSlash(u) {
        const url = new URL(u);
        url.pathname += url.pathname.endsWith("/") ? "" : "/";
        return url.toString();
    }
    
    addTrailingSlash('http://example.com/slug?page=2');
    // result: "http://example.com/slug/?page=2"
    

    您可以在MDN 上阅读有关URL 的更多信息

    【讨论】:

    • 这是最好的答案,因为它将输入视为 URL,而不是字符串。
    【解决方案7】:

    在找到这个问题及其答案之前,我创建了自己的方法。我在这里发布它,因为我没有看到类似的东西。

    function addSlashToUrl() {
        //If there is no trailing shash after the path in the url add it
        if (window.location.pathname.endsWith('/') === false) {
            var url = window.location.protocol + '//' + 
                    window.location.host + 
                    window.location.pathname + '/' + 
                    window.location.search;
    
            window.history.replaceState(null, document.title, url);
        }
    }
    

    【讨论】:

    • history.replaceState 正是我一直在寻找的。它允许添加尾随斜杠而不进行完整的http 303重定向。非常感谢:)
    【解决方案8】:

    并非每个 URL 都可以在末尾加上斜杠。至少有几个条件不允许:

    • 最后一个斜杠后的字符串类似于index.html
    • 有参数:/page?foo=1&bar=2
    • 有片段链接:/page#tomato

    如果上述情况都不存在,我已经编写了一个添加斜线的函数。还有两个附加功能可用于检查添加斜杠的可能性和将 URL 分成几部分。最后一个不是我的,我已经给出了原始链接的链接。

    const SLASH = '/';
    
    function appendSlashToUrlIfIsPossible(url) {
      var resultingUrl = url;
      var slashAppendingPossible = slashAppendingIsPossible(url);
    
      if (slashAppendingPossible) {
        resultingUrl += SLASH;
      }
    
      return resultingUrl;
    }
    
    function slashAppendingIsPossible(url) {
      // Slash is possible to add to the end of url in following cases:
      //  - There is no slash standing as last symbol of URL.
      //  - There is no file extension (or there is no dot inside part called file name).
      //  - There are no parameters (even empty ones — single ? at the end of URL).
      //  - There is no link to a fragment (even empty one — single # mark at the end of URL).
      var slashAppendingPossible = false;
    
      var parsedUrl = parseUrl(url);
    
      // Checking for slash absence.
      var path = parsedUrl.path;
      var lastCharacterInPath = path.substr(-1);
      var noSlashInPathEnd = lastCharacterInPath !== SLASH;
    
      // Check for extension absence.
      const FILE_EXTENSION_REGEXP = /\.[^.]*$/;
      var noFileExtension = !FILE_EXTENSION_REGEXP.test(parsedUrl.file);
    
      // Check for parameters absence.
      var noParameters = parsedUrl.query.length === 0;
      // Check for link to fragment absence.
      var noLinkToFragment = parsedUrl.hash.length === 0;
    
      // All checks above cannot guarantee that there is no '?' or '#' symbol at the end of URL.
      // It is required to be checked manually.
      var NO_SLASH_HASH_OR_QUESTION_MARK_AT_STRING_END_REGEXP = /[^\/#?]$/;
      var noStopCharactersAtTheEndOfRelativePath = NO_SLASH_HASH_OR_QUESTION_MARK_AT_STRING_END_REGEXP.test(parsedUrl.relative);
    
      slashAppendingPossible = noSlashInPathEnd && noFileExtension && noParameters && noLinkToFragment && noStopCharactersAtTheEndOfRelativePath;
    
      return slashAppendingPossible;
    }
    
    // parseUrl function is based on following one:
    // http://james.padolsey.com/javascript/parsing-urls-with-the-dom/.
    function parseUrl(url) {
      var a = document.createElement('a');
      a.href = url;
    
      const DEFAULT_STRING = '';
    
      var getParametersAndValues = function (a) {
        var parametersAndValues = {};
    
        const QUESTION_MARK_IN_STRING_START_REGEXP = /^\?/;
        const PARAMETERS_DELIMITER = '&';
        const PARAMETER_VALUE_DELIMITER = '=';
        var parametersAndValuesStrings = a.search.replace(QUESTION_MARK_IN_STRING_START_REGEXP, DEFAULT_STRING).split(PARAMETERS_DELIMITER);
        var parametersAmount = parametersAndValuesStrings.length;
    
        for (let index = 0; index < parametersAmount; index++) {
          if (!parametersAndValuesStrings[index]) {
            continue;
          }
    
          let parameterAndValue = parametersAndValuesStrings[index].split(PARAMETER_VALUE_DELIMITER);
          let parameter = parameterAndValue[0];
          let value = parameterAndValue[1];
    
          parametersAndValues[parameter] = value;
        }
    
        return parametersAndValues;
      };
    
      const PROTOCOL_DELIMITER = ':';
      const SYMBOLS_AFTER_LAST_SLASH_AT_STRING_END_REGEXP = /\/([^\/?#]+)$/i;
      // Stub for the case when regexp match method returns null.
      const REGEXP_MATCH_STUB = [null, DEFAULT_STRING];
      const URL_FRAGMENT_MARK = '#';
      const NOT_SLASH_AT_STRING_START_REGEXP = /^([^\/])/;
      // Replace methods uses '$1' to place first capturing group.
      // In NOT_SLASH_AT_STRING_START_REGEXP regular expression that is the first
      // symbol in case something else, but not '/' has taken first position.
      const ORIGINAL_STRING_PREPENDED_BY_SLASH = '/$1';
      const URL_RELATIVE_PART_REGEXP = /tps?:\/\/[^\/]+(.+)/;
      const SLASH_AT_STRING_START_REGEXP = /^\//;
      const PATH_SEGMENTS_DELIMITER = '/';
    
      return {
        source: url,
        protocol: a.protocol.replace(PROTOCOL_DELIMITER, DEFAULT_STRING),
        host: a.hostname,
        port: a.port,
        query: a.search,
        parameters: getParametersAndValues(a),
        file: (a.pathname.match(SYMBOLS_AFTER_LAST_SLASH_AT_STRING_END_REGEXP) || REGEXP_MATCH_STUB)[1],
        hash: a.hash.replace(URL_FRAGMENT_MARK, DEFAULT_STRING),
        path: a.pathname.replace(NOT_SLASH_AT_STRING_START_REGEXP, ORIGINAL_STRING_PREPENDED_BY_SLASH),
        relative: (a.href.match(URL_RELATIVE_PART_REGEXP) || REGEXP_MATCH_STUB)[1],
        segments: a.pathname.replace(SLASH_AT_STRING_START_REGEXP, DEFAULT_STRING).split(PATH_SEGMENTS_DELIMITER)
      };
    }

    在某些情况下可能无法添加斜线。如果你知道一些,请评论我的答案。

    【讨论】:

      【解决方案9】:

      对于那些使用不同输入的人:如http://example.comhttp://example.com/eee。在第二种情况下,它不应添加尾部斜杠。

      有一个使用 .href 的序列化选项,它只会在域(主机)之后添加斜杠。

      在 NodeJs 中,

      You would use the url module like this: 
      const url = require ('url');
      let jojo = url.parse('http://google.com')
      console.log(jojo);
      

      在纯 JS 中,你会使用

      var url = document.getElementsByTagName('a')[0];
      var myURL = "http://stackoverflow.com";
      console.log(myURL.href);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-31
        相关资源
        最近更新 更多