web-dev-qa-db-fra.com

Puis-je utiliser require ("chemin"). Join pour concaténer en toute sécurité des URL?

Est-ce sûr d’utiliser require("path").join pour concaténer des URL, par exemple:

require("path").join("http://example.com", "ok"); 
//returns 'http://example.com/ok'

require("path").join("http://example.com/", "ok"); 
//returns 'http://example.com/ok'

Si non, que suggéreriez-vous pour le faire sans écrire un code plein de if?

93
Renato Gama

N ° path.join() renverra des valeurs incorrectes lorsqu'il est utilisé avec des URL.

On dirait que tu veux url.resolve. De la documentation sur les nœuds :

url.resolve('/one/two/three', 'four')         // '/one/two/four'
url.resolve('http://example.com/', '/one')    // 'http://example.com/one'
url.resolve('http://example.com/one', '/two') // 'http://example.com/two'

Edit: Comme Andreas le souligne correctement dans un commentaire, url.resolve _ n’aidera que si le problème est aussi simple que l’exemple. url.parse s'applique également à cette question car elle renvoie des champs de manière cohérente et prévisible via l'objet URL qui réduit le besoin de "code plein de ifs".

109
Matthew Bakaitis

Non, vous ne devez pas utiliser path.join() pour joindre des éléments URL.

Il y a un paquet pour le faire maintenant. Donc plutôt que de réinventer la roue, écrivez tous vos propres tests, trouvez les bogues, corrigez-les, écrivez plus de tests, trouvez un cas Edge où cela ne fonctionne pas, etc., vous pourriez utiliser ce paquet.

uRL-rejoindre

https://github.com/jfromaniello/url-join

Installer

npm install url-join

Usage

var urljoin = require('url-join');

var fullUrl = urljoin('http://www.google.com', 'a', '/b/cd', '?foo=123');

console.log(fullUrl);

Impressions:

' http://www.google.com/a/b/cd?foo=12 '

36
stone

Lorsque j'ai essayé PATH pour concaténer des parties d'URL, j'ai rencontré des problèmes. PATH.join stripes '//' jusqu'à '/' et invalide ainsi une adresse URL absolue (par exemple, http: // ... -> http:/...). Pour moi, une solution rapide était:

baseurl.replace(/\/$/,"") + '/' + path.replace(/^\//,"") )

ou avec la solution publiée par le colonel Panic:

[pathA.replace(/^\/|\/$/g,""),pathB.replace(/^\/|\/$/g,"")].join("/")
6
Peter

Non! Sous Windows path.join va rejoindre avec des barres obliques inverses. Les URL HTTP sont toujours des barres obliques.

Que diriez-vous

> ["posts", "2013"].join("/")
'posts/2013'
6
Colonel Panic

Nous le faisons comme ça:

var _ = require('lodash');

function urlJoin(a, b) {
  return _.trimEnd(a, '/') + '/' + _.trimStart(b, '/');
}
4
Peter Dotchev

Axios dispose d'une fonction d'assistance permettant de combiner des URL.

function combineURLs(baseURL, relativeURL) {
  return relativeURL
    ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '')
    : baseURL;
}

Source: https://github.com/axios/axios/blob/fe7d09bb08fa1c0e414956b7fc760c80459b0a43/lib/helpers/combineURLs.js

4
Ikbel

C'est ce que j'utilise:

function joinUrlElements() {
  var re1 = new RegExp('^\\/|\\/$','g'),
      elts = Array.prototype.slice.call(arguments);
  return elts.map(function(element){return element.replace(re1,""); }).join('/');
}

exemple:

url = joinUrlElements(config.mgmtServer, '/v1/o/', config.org, '/apps');
3
Cheeso

Si vous utilisez Angular, vous pouvez utiliser Location :

import { Location } from '@angular/common';
// ...
Location.joinWithSlash('beginning', 'end');

Ne fonctionne que sur 2 arguments, vous devez donc chaîner les appels ou écrire une fonction d'assistance pour le faire si nécessaire.

2
Mic

Si vous utilisez lodash, vous pouvez utiliser ce simple oneliner:

// returns part1/part2/part3
['part1/', '/part2', '/part3/'].map((s) => _.trim(s, '/')).join('/')

inspiré par @ Peter Dotchev's answer

2
M K

Le constructeur objet URL WHATWG a un (input, base) version, et le input peut être relatif en utilisant /, ./, ../. Combinez cela avec path.posix.join et vous pouvez faire n'importe quoi:

const {posix} = require ("path");
const withSlash = new URL("https://example.com:8443/something/");
new URL(posix.join("a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/something/a/b/c'
new URL(posix.join("./a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/something/a/b/c'
new URL(posix.join("/a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/a/b/c'
new URL(posix.join("../a", "b", "c"), withSlash).toString(); // 'https://example.com:8443/a/b/c'
const noSlash = new URL("https://example.com:8443/something");
new URL(posix.join("./a", "b", "c"), noSlash).toString(); // 'https://example.com:8443/a/b/c'
0
Coderer

Solution personnalisée TypeScript:

export function pathJoin(parts: string[], sep: string) {
  return parts
    .map(part => {
      const part2 = part.endsWith(sep) ? part.substring(0, part.length - 1) : part;
      return part2.startsWith(sep) ? part2.substr(1) : part2;
    })
    .join(sep);
}

expect(pathJoin(['a', 'b', 'c', 'd'], '/')).toEqual('a/b/c/d');
expect(pathJoin(['a/', '/b/', 'c/', 'd'], '/')).toEqual('a/b/c/d');
expect(pathJoin(['http://abc.de', 'users/login'], '/')).toEqual('http://abc.de/users/login');
0
Patrick Wozniak