Search code examples
d3.jswebserver

Why do I need to start a web server to use d3?


I read various d3js tutorials and nobody is explained why to use d3 you need to start a web server (whether in Python or Node, ...).

So, why is it necessary?


Solution

  • Sometimes it's not necessary. But in general, it's a good idea to replicate the environment that your code will be viewed in so you don't run into unforeseen issues when you publish or unnecessary frustrations due to using an environment not intended for your technology.

    d3 is intended to run in the browser, with some parts of it requiring to be run on a web page for certain browsers. In my experience, the issues that arise from opening a d3 page directly in browser using the file URI, i.e. file://, are split into two categories: security and schemeless urls.

    Security Limitations

    The file:// protocol often has additional limitations. Particularly relevant to d3 is the restrictions of using XMLHttpRequest (used in d3v4 and below) and fetch (used in d3v5), which form the basis for loading data files (e.g. using d3.csv).

    Chrome, and other browsers, does not normally allow XMLHttpRequest or fetch requests to local files. You may get an error that says something like:

    Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https

    You can read more about how to enable asynchronous reading from local files and the reasoning behind disabling it by default from this answer: https://stackoverflow.com/a/18137280/6184972

    Firefox, however, does not seem to have this restriction.

    Schemeless Urls

    Some d3 examples, particularly older ones, include d3 using this convention:

    <script src="//d3js.org/d3.v3.min.js"></script>
    

    The //d3js.org is a Schemeless Url (also known as Protocol-Relative Urls) which means that the browser can decide what protocol to use. That means it will use https://d3js.org if the loading page uses https, and (maybe) http://d3js.org if the loading page uses http.

    Unfortunately when loading a file through the file:// protocol, this means that the aforementioned URL will refer to file://d3js.org/d3.v3.min.js, which usually isn't what is intended. In this case you may get an error like:

    GET file://d3js.org/d3.v3.min.js net::ERR_FILE_NOT_FOUND

    Uncaught ReferenceError: d3 is not defined

    Using Schemeless Urls has fallen out of favor, in lieu of always using https:// instead. See: https://stackoverflow.com/a/31100809/6184972

    If this is the only issue that you're running into, it may be solvable by including the protocol (i.e. changing src="//d3js.org/d3.v3.min.js" to src="https://d3js.org/d3.v3.min.js"

    Additional references:

    https://developer.mozilla.org/en-US/docs/Learn/Common_questions/set_up_a_local_testing_server#The_problem_with_testing_local_files