Можно ли использовать браузер в качестве веб-сервера? Сан-операция, учиться бесполезно~

внешний интерфейс JavaScript PWA
Можно ли использовать браузер в качестве веб-сервера? Сан-операция, учиться бесполезно~

Это 21-й день моего участия в ноябрьском испытании обновлений. Узнайте подробности события:Вызов последнего обновления 2021 г.

клин

Какой? Можно ли использовать браузер в качестве веб-сервера?

Сплетни меньше, непосредственно сухие товары!

Общая идея: рабочие серверы, используемые для кэширования файлов в PWA, могут динамически генерировать новые файлы и отправлять их в браузер через событие fetch!

  • Друзья, не знакомые с PWA, могут просто понять это следующим образом:

PWA (прогрессивные веб-приложения) переводится какПрогрессивные веб-приложения, что является новой идеей создания веб-приложений с участиемНемногоКонкретная картина, API и другие функции.

Он делает то, что традиционный Интернет не может:Работает в автономном режиме, устанавливается, легко синхронизируется, может отправлять push-уведомления и т. д.;

  • Друзья, не знакомые с серверными работниками, могут понять просто так:

Серверные воркеры выполняют посредническую роль между сервером и браузером.Если сервисный воркер зарегистрирован на сайте, он может перехватывать все запросы текущего сайта и выносить решения (необходимо написать соответствующую программу-оценку).Если вам нужно инициировать запрос к серверу Просто перенаправить его на сервер.Если кеш можно использовать напрямую, вернуть кеш напрямую и больше не передавать его на сервер. Тем самым значительно улучшая опыт просмотра.

Итак, через серверные рабочие можно отправлять файлы в браузер!

инструмент

  • Мы также будем использовать:somorphic-git

somorphic-git — реализация git на чистом JavaScript для сред Node и браузеров (включая WebWorkers и ServiceWorkers);

Его можно использовать для чтения и записи репозиториев git, а также для извлечения и отправки из Github.

  • Мы также будем использоватьBrowserFS

BrowserFS похож на Webpack и также является инструментом упаковки модулей;

Его особенности:

  1. Дизайн, основанный на идее потока
  2. Его можно использовать через командную строку или через API
  3. обрабатывать только javascript
  4. Обратный процесс модуляризации, но способствует лучшему развитию модульности.
  5. Встроен в некоторыеnode core module
  6. Модули узлов можно использовать на стороне браузера, даизоморфное приложениемощное оружие
  • Мы также будем использоватьLightning-fs

Это позволяет браузеру быстрее читать и записывать файлы, молниеносно ⚡ ~

выполнить

Код:

/**@license
 *   ___ ___ _____  __      __   _      _____              _           _
 *  / __|_ _|_   _| \ \    / /__| |__  |_   _|__ _ _ _ __ (_)_ _  __ _| |
 * | (_ || |  | |    \ // / -_) '_ \   | |/ -_) '_| '  | | ' / _` | |
 *  ___|___| |_|     _/_/___|_.__/   |_|___|_| |_|_|_|_|_||___,_|_|
 *
 * this is service worker and it's part of GIT Web terminal
 *
 * Copyright (c) 2018 Jakub Jankiewicz <http://jcubic.pl/me>
 * Released under the MIT license
 *
 */
/* global BrowserFS, Response, setTimeout, fetch, Blob, Headers */
self.importScripts('https://cdn.jsdelivr.net/npm/browserfs');

self.addEventListener('install', self.skipWaiting);

self.addEventListener('activate', self.skipWaiting);

self.addEventListener('fetch', function (event) {
    let path = BrowserFS.BFSRequire('path');
    let fs = new Promise(function(resolve, reject) {
        BrowserFS.configure({ fs: 'IndexedDB', options: {} }, function (err) {
            if (err) {
                reject(err);
            } else {
                resolve(BrowserFS.BFSRequire('fs'));
            }
        });
    });
    event.respondWith(fs.then(function(fs) {
        return new Promise(function(resolve, reject) {
            function sendFile(path) {
                fs.readFile(path, function(err, buffer) {
                    if (err) {
                        err.fn = 'readFile(' + path + ')';
                        return reject(err);
                    }
                    var ext = path.replace(/.*./, '');
                    var mime = {
                        'html': 'text/html',
                        'json': 'application/json',
                        'js': 'application/javascript',
                        'css': 'text/css'
                    };
                    var headers = new Headers({
                        'Content-Type': mime[ext]
                    });
                    resolve(new Response(buffer, {headers}));
                });
            }
            var url = event.request.url;
            var m = url.match(/__browserfs__(.*)/);
            function redirect_dir() {
                return resolve(Response.redirect(url + '/', 301));
            }
            function serve() {
                fs.stat(path, function(err, stat) {
                    if (err) {
                        return resolve(textResponse(error404Page(path)));
                    }
                    if (stat.isFile()) {
                        sendFile(path);
                    } else if (stat.isDirectory()) {
                        if (path.substr(-1, 1) !== '/') {
                            return redirect_dir();
                        }
                        fs.readdir(path, function(err, list) {
                            if (err) {
                                err.fn = 'readdir(' + path + ')';
                                return reject(err);
                            }
                            var len = list.length;
                            if (list.includes('index.html')) {
                                sendFile(path + '/index.html');
                            } else {
                                listDirectory({fs, path, list}).then(function(list) {
                                    resolve(textResponse(fileListingPage(path, list)));
                                }).catch(reject);
                            }
                        });
                    }
                });
            }
            if (m) {
                var path = m[1];
                if (path === '') {
                    return redirect_dir();
                }
                console.log('serving ' + path + ' from browserfs');
                serve();
            } else {
                if (event.request.cache === 'only-if-cached' && event.request.mode !== 'same-origin') {
                    return;
                }
                //request = credentials: 'include'
                fetch(event.request).then(resolve).catch(reject);
            }
        });
    }));
});
// -----------------------------------------------------------------------------
function listDirectory({fs, path, list}) {
    return new Promise(function(resolve, reject) {
        var items = [];
        (function loop() {
            var item = list.shift();
            if (!item) {
                return resolve(items);
            }
            fs.stat(path + '/' + item, function(err, stat) {
                if (err) {
                    err.fn = 'stat(' + path + '/' + item + ')';
                    return reject(err);
                }
                items.push(stat.isDirectory() ? item + '/' : item);
                loop();
            });
        })();
    });
}

// -----------------------------------------------------------------------------
function textResponse(string, filename) {
    var blob = new Blob([string], {
        type: 'text/html'
    });
    return new Response(blob);
}

// -----------------------------------------------------------------------------
function fileListingPage(path, list) {
    var output = [
        '<!DOCTYPE html>',
        '<html>',
        '<body>',
        `<h1>BrowserFS ${path}</h1>`,
        '<ul>'
    ];
    if (path.match(/^/(.*/)/)) {
        output.push('<li><a href="..">..</a></li>');
    }
    list.forEach(function(name) {
        output.push('<li><a href="' + name + '">' + name + '</a></li>');
    });
    output = output.concat(['</ul>', '</body>', '</html>']);
    return output.join('\n');
}

// -----------------------------------------------------------------------------
function error404Page(path) {
    var output = [
        '<!DOCTYPE html>',
        '<html>',
        '<body>',
        '<h1>404 File Not Found</h1>',
        `<p>File ${path} not found in browserfs`,
        '</body>',
        '</html>'
    ];
    return output.join('\n');
}

Инициализируйте обслуживающий работник следующим образом:

if ('serviceWorker' in navigator) {
var scope = location.pathname.replace(/\/[^\/]+$/, '/');
if (!scope.match(/__browserfs__/)) {
navigator.serviceWorker.register('sw.js', {scope})
.then(function(reg) {
reg.addEventListener('updatefound', function() {
var installingWorker = reg.installing;
console.log('A new service worker is being installed:',
installingWorker);
});
// registration worked
console.log('Registration succeeded. Scope is ' +
reg.scope);
}).catch(function(error) {
// registration failed
console.log('Registration failed with ' + error);
});
}
}

тестовое задание

оригинальный авторJakub T. JankiewiczТакже сделал онлайн-тест ДемоGIT Web Terminal, что я могу сказать, кроме NB?

Вызов теста:

vi test.txt

i Hello World :wq

view test.txt

Просмотр возвращает:

image.png

Есть поговорка, суд в этом направлении все еще очень вершин ~~

Мы обязаны расширять наши веб-возможности! (●'◡'●)


Хорошо, это то, что вы делитесь этой статьей~ Писать статьи непросто, пожалуйста, ставьте лайки и поощряйте 👍👍👍

Ссылка на эту статью:

Я Энтони Наггетс, у публичного аккаунта такое же имя, я пешка, и я золотой самородок, до свидания~