javascript/jquery向url添加尾斜杠(如果不存在)

时间:2021-08-06 10:45:31

I'm making a small web app in which a user enters a server URL from which it pulls a load of data with an AJAX request.

我正在开发一个小型web应用程序,用户在其中输入一个服务器URL,通过AJAX请求从该URL获取大量数据。

Since the user has to enter the URL manually, people generally forget the trailing slash, even though it's required (as some data is appended to the url entered). I need a way to check if the slash is present, and if not, add it.

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

This seems like a problem that jQuery would have a one-liner for, does anyone know how to do this or should I write a JS function for it?

这似乎是jQuery有一行代码的问题,有人知道怎么做吗?或者我应该为它编写一个JS函数吗?

7 个解决方案

#1


91  

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

The temporary variable name can be omitted, and directly embedded in the assertion:

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

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

Since the goal is changing the url with a one-liner, the following solution can also be used:

由于目标是使用一行程序更改url,因此还可以使用以下解决方案:

url = url.replace(/\/?$/, '/');
  • If the trailing slash exists, it is replaced with /.
  • 如果末尾的斜杠存在,则用/替换。
  • If the trailing slash does not exist, a / is appended to the end (to be exact: The trailing anchor is replaced with /).
  • 如果尾斜杠不存在,则将a /追加到末尾(确切地说:用/替换尾锚)。

#2


16  

url += url.endsWith("/") ? "" : "/"

#3


8  

I added to the regex solution to accommodate query strings:

我添加了regex解决方案以适应查询字符串:

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

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

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

#4


3  

You can do something like:

你可以这样做:

var url = 'http://*.com';

if (!url.match(/\/$/)) {
    url += '/';
}

Here's the proof: http://jsfiddle.net/matthewbj/FyLnH/

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

#5


2  

Before finding this question and it's answers I created my own approach. I post it here as I don't see something similar.

在找到这个问题和它的答案之前,我创造了我自己的方法。我把它贴在这里,因为我没有看到类似的东西。

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

#6


1  

This works as well:

这是:

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

Example:

例子:

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

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

Output:

输出:

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

#7


0  

Not every URL can be completed with slash at the end. There are at least several conditions that do not allow one:

不是每个URL都可以用斜杠来完成。至少有几个条件是不允许的:

  • String after last existing slash is something like index.html.
  • 字符串后面的最后一个现有的斜杠是类似于index.html的东西。
  • There are parameters: /page?foo=1&bar=2.
  • 有参数:/页面? foo = 1就是= 2。
  • There is link to fragment: /page#tomato.
  • 有链接到片段:/页面#番茄。

I have written a function for adding slash if none of the above cases are present. There are also two additional functions for checking the possibility of adding slash and for breaking URL into parts. Last one is not mine, I've given a link to the original one.

我已经编写了一个函数来添加斜杠,如果没有上述情况。另外还有两个函数,用于检查添加斜杠和将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)
  };
}

There might also be several cases when adding slash is not possible. If you know some, please comment my answer.

在不可能添加斜杠的情况下,可能还会出现一些情况。如果你知道一些,请评论我的回答。

#1


91  

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

The temporary variable name can be omitted, and directly embedded in the assertion:

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

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

Since the goal is changing the url with a one-liner, the following solution can also be used:

由于目标是使用一行程序更改url,因此还可以使用以下解决方案:

url = url.replace(/\/?$/, '/');
  • If the trailing slash exists, it is replaced with /.
  • 如果末尾的斜杠存在,则用/替换。
  • If the trailing slash does not exist, a / is appended to the end (to be exact: The trailing anchor is replaced with /).
  • 如果尾斜杠不存在,则将a /追加到末尾(确切地说:用/替换尾锚)。

#2


16  

url += url.endsWith("/") ? "" : "/"

#3


8  

I added to the regex solution to accommodate query strings:

我添加了regex解决方案以适应查询字符串:

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

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

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

#4


3  

You can do something like:

你可以这样做:

var url = 'http://*.com';

if (!url.match(/\/$/)) {
    url += '/';
}

Here's the proof: http://jsfiddle.net/matthewbj/FyLnH/

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

#5


2  

Before finding this question and it's answers I created my own approach. I post it here as I don't see something similar.

在找到这个问题和它的答案之前,我创造了我自己的方法。我把它贴在这里,因为我没有看到类似的东西。

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

#6


1  

This works as well:

这是:

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

Example:

例子:

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

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

Output:

输出:

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

#7


0  

Not every URL can be completed with slash at the end. There are at least several conditions that do not allow one:

不是每个URL都可以用斜杠来完成。至少有几个条件是不允许的:

  • String after last existing slash is something like index.html.
  • 字符串后面的最后一个现有的斜杠是类似于index.html的东西。
  • There are parameters: /page?foo=1&bar=2.
  • 有参数:/页面? foo = 1就是= 2。
  • There is link to fragment: /page#tomato.
  • 有链接到片段:/页面#番茄。

I have written a function for adding slash if none of the above cases are present. There are also two additional functions for checking the possibility of adding slash and for breaking URL into parts. Last one is not mine, I've given a link to the original one.

我已经编写了一个函数来添加斜杠,如果没有上述情况。另外还有两个函数,用于检查添加斜杠和将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)
  };
}

There might also be several cases when adding slash is not possible. If you know some, please comment my answer.

在不可能添加斜杠的情况下,可能还会出现一些情况。如果你知道一些,请评论我的回答。