123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- "use strict";
- module.exports = fetch;
-
- var asPromise = require("@protobufjs/aspromise"),
- inquire = require("@protobufjs/inquire");
-
- var fs = inquire("fs");
-
- /**
- * Node-style callback as used by {@link util.fetch}.
- * @typedef FetchCallback
- * @type {function}
- * @param {?Error} error Error, if any, otherwise `null`
- * @param {string} [contents] File contents, if there hasn't been an error
- * @returns {undefined}
- */
-
- /**
- * Options as used by {@link util.fetch}.
- * @typedef FetchOptions
- * @type {Object}
- * @property {boolean} [binary=false] Whether expecting a binary response
- * @property {boolean} [xhr=false] If `true`, forces the use of XMLHttpRequest
- */
-
- /**
- * Fetches the contents of a file.
- * @memberof util
- * @param {string} filename File path or url
- * @param {FetchOptions} options Fetch options
- * @param {FetchCallback} callback Callback function
- * @returns {undefined}
- */
- function fetch(filename, options, callback) {
- if (typeof options === "function") {
- callback = options;
- options = {};
- } else if (!options)
- options = {};
-
- if (!callback)
- return asPromise(fetch, this, filename, options); // eslint-disable-line no-invalid-this
-
- // if a node-like filesystem is present, try it first but fall back to XHR if nothing is found.
- if (!options.xhr && fs && fs.readFile)
- return fs.readFile(filename, function fetchReadFileCallback(err, contents) {
- return err && typeof XMLHttpRequest !== "undefined"
- ? fetch.xhr(filename, options, callback)
- : err
- ? callback(err)
- : callback(null, options.binary ? contents : contents.toString("utf8"));
- });
-
- // use the XHR version otherwise.
- return fetch.xhr(filename, options, callback);
- }
-
- /**
- * Fetches the contents of a file.
- * @name util.fetch
- * @function
- * @param {string} path File path or url
- * @param {FetchCallback} callback Callback function
- * @returns {undefined}
- * @variation 2
- */
-
- /**
- * Fetches the contents of a file.
- * @name util.fetch
- * @function
- * @param {string} path File path or url
- * @param {FetchOptions} [options] Fetch options
- * @returns {Promise<string|Uint8Array>} Promise
- * @variation 3
- */
-
- /**/
- fetch.xhr = function fetch_xhr(filename, options, callback) {
- var xhr = new XMLHttpRequest();
- xhr.onreadystatechange /* works everywhere */ = function fetchOnReadyStateChange() {
-
- if (xhr.readyState !== 4)
- return undefined;
-
- // local cors security errors return status 0 / empty string, too. afaik this cannot be
- // reliably distinguished from an actually empty file for security reasons. feel free
- // to send a pull request if you are aware of a solution.
- if (xhr.status !== 0 && xhr.status !== 200)
- return callback(Error("status " + xhr.status));
-
- // if binary data is expected, make sure that some sort of array is returned, even if
- // ArrayBuffers are not supported. the binary string fallback, however, is unsafe.
- if (options.binary) {
- var buffer = xhr.response;
- if (!buffer) {
- buffer = [];
- for (var i = 0; i < xhr.responseText.length; ++i)
- buffer.push(xhr.responseText.charCodeAt(i) & 255);
- }
- return callback(null, typeof Uint8Array !== "undefined" ? new Uint8Array(buffer) : buffer);
- }
- return callback(null, xhr.responseText);
- };
-
- if (options.binary) {
- // ref: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Sending_and_Receiving_Binary_Data#Receiving_binary_data_in_older_browsers
- if ("overrideMimeType" in xhr)
- xhr.overrideMimeType("text/plain; charset=x-user-defined");
- xhr.responseType = "arraybuffer";
- }
-
- xhr.open("GET", filename);
- xhr.send();
- };
|