Can I use require(“path”).join to safely concatenate urls?

前端 未结 15 524
臣服心动
臣服心动 2020-12-23 13:06

Is this safe to use require(\"path\").join to concatenate URLs, for example:

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


        
相关标签:
15条回答
  • 2020-12-23 13:21

    We do it like this:

    var _ = require('lodash');
    
    function urlJoin(a, b) {
      return _.trimEnd(a, '/') + '/' + _.trimStart(b, '/');
    }
    
    0 讨论(0)
  • 2020-12-23 13:25

    No! On Windows path.join will join with backslashes. HTTP urls are always forward slashes.

    How about

    > ["posts", "2013"].join("/")
    'posts/2013'
    
    0 讨论(0)
  • 2020-12-23 13:25

    If you're using lodash, you can use this simple oneliner:

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

    inspired by @Peter Dotchev's answer

    0 讨论(0)
  • 2020-12-23 13:26

    Typescript custom solution:

    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 讨论(0)
  • 2020-12-23 13:27

    No. path.join() will return incorrect values when used with URLs.

    It sounds like you want new URL(). From the WHATWG URL Standard:

    new URL('/one', 'http://example.com/').href    // 'http://example.com/one'
    new URL('/two', 'http://example.com/one').href // 'http://example.com/two'
    

    Note that url.resolve is now marked as deprecated in the Node docs.

    As Andreas correctly points out in a comment, url.resolve (also deprecated) would only help if the problem is as simple as the example. url.parse also applies to this question because it returns consistently and predictably formatted fields via the URL object that reduces the need for "code full of ifs". However, new URL() is also the replacement for url.parse.

    0 讨论(0)
  • 2020-12-23 13:32

    My solution

    path.join(SERVER_URL, imageAbsolutePath).replace(':/','://');
    

    Edit: if you want to support windows enviroments

    path.join(SERVER_URL, imageAbsolutePath).replace(/\\/g,'/').replace(':/','://');
    

    The second solution will replace all the backslashes, so url parts like querystring and hash may be altered too, but the topic is joining just the url path, so I don't consider it an issue.

    0 讨论(0)
提交回复
热议问题