How to convert local file path to a file::?/ url safely in node.js?

40,992

Solution 1

Use the file-url module.

npm install --save file-url

Usage:

var fileUrl = require('file-url');

fileUrl('unicorn.jpg');
//=> file:///Users/sindresorhus/dev/file-url/unicorn.jpg 

fileUrl('/Users/pony/pics/unicorn.jpg');
//=> file:///Users/pony/pics/unicorn.jpg

Also works in Windows. And the code is simple enough, in case you want to just take a snippet:

var path = require('path');

function fileUrl(str) {
    if (typeof str !== 'string') {
        throw new Error('Expected a string');
    }

    var pathName = path.resolve(str).replace(/\\/g, '/');

    // Windows drive letter must be prefixed with a slash
    if (pathName[0] !== '/') {
        pathName = '/' + pathName;
    }

    return encodeURI('file://' + pathName);
};

Solution 2

Node.js v10.12.0 just got two new methods to solve this issue:

const url = require('url');
url.fileURLToPath(url)
url.pathToFileURL(path)

Documentation

Solution 3

I had a similar issue, but the solution ended up being to use the new WHATWG URL implementation:

const path = 'c:\\Users\\myname\\test.swf';
const u = new URL(`file:///${path}`).href;
// u = 'file:///c:/Users/myname/test.swf'
Share:
40,992

Related videos on Youtube

Bartvds
Author by

Bartvds

Updated on January 29, 2020

Comments

  • Bartvds
    Bartvds over 4 years

    I have local file paths (in node.js) and I need to convert them into file:// urls.

    I'm now looking at https://en.wikipedia.org/wiki/File_URI_scheme and I feel this must be a solved problem and somebody must have a snippet or npm module to do this.

    But then I try to search npm for this but I get so much cruft it is not funny (file, url and path are a search hit in like every package ever :) Same with google and SO.

    I can do this naïve approach

    site = path.resolve(site);
    if (path.sep === '\\') {
        site = site.split(path.sep).join('/');
    }
    if (!/^file:\/\//g.test(site)) {
        site = 'file:///' + site;
    }
    

    But I'm pretty sure that is not the way to go.

    • Brian
      Brian over 10 years
      See this post for possible solution: stackoverflow.com/questions/18341808/…
    • idmean
      idmean almost 10 years
      Did you ever find a solution?
    • Bartvds
      Bartvds almost 10 years
      @wumm not really, I just use a naïve regexp based replacement like above commenter.
  • Bartvds
    Bartvds over 9 years
    Thanks, this is what I was looking for back when I posted the question, I'll accept it for posterity.
  • Mike Samuel
    Mike Samuel over 5 years
    This might break down if path contains any of ?, #, or %.
  • Robert G. Schaffrath
    Robert G. Schaffrath about 3 years
    As of file-url version 4.0.0, the developer requires ESM, Node.js 12.0.0+ and no longer supports CommonJS (an error is thrown if you try to use require). Version 3.0.0 still works but 4.0.0 imposes these constraints that may not be acceptable to many developers. I am going to check out the url module and pathToFileURL() method.