it-swarm.com.de

Kann ich require ("path"). Join verwenden, um URLs sicher zu verketten?

Ist es sicher, require("path").join zu verwenden, um URLs zu verketten, zum Beispiel:

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

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

Wenn nicht, wie würden Sie dies tun, ohne einen Code voller ifs zu schreiben?

93
Renato Gama

Nein. path.join() gibt bei Verwendung mit URLs falsche Werte zurück.

Es klingt wie Sie wollen url.resolve. Aus dem Node docs :

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: Wie Andreas in einem Kommentar richtig hervorhebt, url.resolve würde nur helfen, wenn das Problem so einfach wie das Beispiel ist. url.parse gilt auch für diese Frage, da konsistent und vorhersehbar formatierte Felder über das Objekt URL zurückgegeben werden, wodurch der Bedarf an "Code voller ifs" verringert wird.

109

Nein, Sie sollten path.join() nicht verwenden, um URL-Elemente zu verbinden.

Dafür gibt es jetzt ein Paket. Also anstatt das Rad neu zu erfinden, schreiben Sie alle Ihre eigenen Tests, finden Sie Fehler, beheben Sie sie, schreiben Sie weitere Tests, finden Sie einen Edge-Fall, in dem es nicht funktioniert, usw. Sie könnten dieses Paket verwenden.

uRL-Join

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

Installieren

npm install url-join

Verwendung

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

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

console.log(fullUrl);

Drucke:

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

36
stone

Als ich PATH zum Verketten von URL-Teilen ausprobierte, stieß ich auf Probleme. PATH.join streift '//' nach '/' und macht auf diese Weise eine absolute URL ungültig (zB http: // ... -> http:/...). Für mich war eine schnelle Lösung:

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

oder mit der Lösung von Colonel Panic:

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

Nein! Unter Windows path.join schließt sich mit Backslashes an. HTTP-URLs sind immer Schrägstriche.

Wie wäre es mit

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

Wir machen es so:

var _ = require('lodash');

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

Axios verfügt über eine Hilfsfunktion, mit der URLs kombiniert werden können.

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

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

4
Ikbel

Das benutze ich:

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

beispiel:

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

Wenn Sie Angular verwenden, können Sie Location verwenden:

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

Funktioniert jedoch nur mit 2 Argumenten. Sie müssen also Aufrufe verketten oder eine Hilfsfunktion schreiben, um dies bei Bedarf zu tun.

2
Mic

Wenn Sie lodash verwenden, können Sie diesen einfachen Oneliner verwenden:

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

inspiriert von @ Peter Dotchevs Antwort

2
M K

Der Konstruktor WHATWG-URL-Objekt hat eine (input, base) -Version, und der input kann mit /, ./ relativ sein. , ../. Kombiniere dies mit path.posix.join und du kannst alles machen:

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

Benutzerdefinierte TypeScript-Lösung:

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