返回介绍

主进程生产环境加载本地文件

发布于 2024-09-11 01:11:54 字数 2538 浏览 0 评论 0 收藏 0

虽然成功制作了安装包,而且这个安装包可以正确安装应用程序,但是这个应用程序无法正常启动,这是因为应用程序的主进程还在通过 process.argv[2] 加载首页。显然用户通过安装包安装的应用程序没有这个参数。

接下来就要让应用程序在没有这个参数的时候,也能加载静态页面。

新建 src\main\CustomScheme.ts:

import { protocol } from 'electron';
import path from 'path';
import fs from 'fs';

// 为自定义 app 协议提供特权
let schemeConfig = {
  standard: true,
  supportFetchAPI: true,
  bypassCSP: true,
  corsEnabled: true,
  stream: true,
};

protocol.registerSchemesAsPrivileged([{
  scheme: 'app',
  privileges: schemeConfig,
}]);

export class CustomScheme {
  // 根据文件扩展名获取 mime-type
  private static getMimeType(extension: string) {
    let mineType = '';
    switch (extension) {
      case '.js':
        mineType = 'text/javascript';
      break;
      case '.html':
        mineType = 'text/html';
      break;
      case '.css':
        mineType = 'text/css';
      break;
      case '.svg':
        mineType = 'image/svg+xml';
      break;
      case '.json':
        mineType = 'application/json';
      break;
    }
    return mineType;
  };
  // 注册自定义 app 协议
  static registerScheme() {
    protocol.registerStreamProtocol('app', (request, callback) => {
      let pathName = new URL(request.url).pathname;
      let extension = path.extname(pathName).toLowerCase();
      if (extension === '') {
        pathName = 'index.html';
        extension = '.html';
      }
      let tarFile = path.join(__dirname, pathName);
      callback({
        statusCode: 200,
        headers: {
          'content-type': this.getMimeType(extension),
        },
        data: fs.createReadStream(tarFile),
      })
    });
  };
}

在主进程 app ready 前,通过 protocol 对象的 registerSchemesAsPrivileged 方法为名为 app 的 scheme 注册了特权(可以使用 FetchAPI、绕过内容安全策略等)。

在 app ready 之后,通过 protocol 对象的 registerStreamProtocol 方法为名为 app 的 scheme 注册了一个回调函数。当加载类似 app://index.html 这样的路径时,这个回调函数将被执行。

这个函数有两个传入参数 request 和 callback,通过 request.url 获取到请求的文件路径,通过 callback 做出响应。

给出响应时,要指定响应的 statusCode 和 content-type,这个 content-type 是通过文件的扩展名得到的。这里通过 getMimeType 方法确定了文件的 content-type。

响应的 data 属性为目标文件的可读数据流,当你的静态文件比较大时,不必读出整个文件再给出响应。

接下来在 src\main\mainEntry.ts 中使用这段代码:

import {CustomScheme} from './customScheme';

if (process.argv[2]) {
    mainWindow.loadURL(process.argv[2]);
  } else {
    CustomScheme.registerScheme();
    mainWindow.loadURL('app"//index.html');
  }

这样当存在指定的命令行参数时,就认为是开发环境,使用命令行参数加载页面,当不存在命令行参数时,就认为是生产环境,通过 app:// scheme 加载页面。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文