You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron封装Angular桌面应用的第三方API调用结果缓存方案咨询

HTTP请求缓存实现方案

优先方案:Electron主进程代理缓存

该方案直接在Electron主进程拦截所有渲染进程发起的请求,自定义缓存逻辑,无需修改前端业务代码,无CORS限制,是最适配当前架构的实现方式。

实现逻辑

  1. 选择持久化存储工具,推荐使用electron-store,直接将缓存写入本地文件,应用重启后缓存仍然有效
  2. 通过Electron的webRequest模块匹配需要缓存的公共API规则,拦截对应请求
  3. 自定义缓存TTL(直接设置为24小时,忽略接口返回的短有效期缓存头),请求到达时优先查本地缓存,未过期则直接返回缓存内容,无有效缓存时再发起真实请求,请求返回后写入缓存

代码示例

// 主进程代码,先安装依赖:npm install electron-store node-fetch
const { app, session } = require('electron');
const Store = require('electron-store');
const fetch = require('node-fetch');

// 初始化缓存存储
const cacheStore = new Store({ name: 'api-cache' });
const CACHE_TTL = 24 * 60 * 60 * 1000; // 缓存有效期24小时,单位毫秒
// 替换为你需要缓存的公共API域名正则规则
const CACHE_API_RULE = /^https:\/\/(公共API域名1|公共API域名2)\/.*/;

app.whenReady().then(() => {
  // 拦截渲染进程所有请求
  session.defaultSession.webRequest.onBeforeRequest(async (details, callback) => {
    // 非目标API、非GET请求直接放行,POST请求需额外处理请求体hash作为缓存key
    if (!CACHE_API_RULE.test(details.url) || details.method !== 'GET') {
      return callback({ cancel: false });
    }

    const cacheKey = `cache:${details.method}:${details.url}`;
    const cached = cacheStore.get(cacheKey);

    // 命中有效缓存直接返回
    if (cached && Date.now() - cached.timestamp < CACHE_TTL) {
      return callback({
        cancel: false,
        redirectURL: `data:application/json;charset=utf-8,${encodeURIComponent(cached.data)}`
      });
    }

    // 无有效缓存发起真实请求
    try {
      const resp = await fetch(details.url, {
        method: details.method,
        headers: details.requestHeaders
      });
      const respData = await resp.text();
      const contentType = resp.headers.get('content-type') || 'application/json';
      // 写入缓存
      cacheStore.set(cacheKey, {
        data: respData,
        timestamp: Date.now()
      });
      // 返回请求结果
      callback({
        cancel: false,
        redirectURL: `data:${contentType};charset=utf-8,${encodeURIComponent(respData)}`
      });
    } catch (e) {
      // 请求异常走原有逻辑
      callback({ cancel: false });
    }
  });
});

备选方案:Angular侧HTTP拦截器缓存

如果不希望修改Electron主进程代码,可以在Angular侧通过HTTP拦截器实现缓存,适合小项目快速迭代。

实现逻辑

  1. 实现全局缓存服务,存储请求响应和过期时间,需要持久化可选择IndexedDB
  2. 注册Angular全局HTTP拦截器,匹配目标API规则,请求优先查缓存,命中有效缓存直接返回,否则发起真实请求后写入缓存

代码示例

// 1. 缓存服务 api-cache.service.ts
import { Injectable } from '@angular/core';
import { HttpResponse } from '@angular/common/http';

interface CacheEntry {
  data: HttpResponse<any>;
  timestamp: number;
}

@Injectable({ providedIn: 'root' })
export class ApiCacheService {
  // 需要持久化可替换为IndexedDB实现
  private cache = new Map<string, CacheEntry>();
  private CACHE_TTL = 24 * 60 * 60 * 1000;

  get(url: string): HttpResponse<any> | null {
    const entry = this.cache.get(url);
    if (!entry) return null;
    if (Date.now() - entry.timestamp > this.CACHE_TTL) {
      this.cache.delete(url);
      return null;
    }
    return entry.data;
  }

  set(url: string, data: HttpResponse<any>): void {
    this.cache.set(url, { data, timestamp: Date.now() });
  }
}

// 2. 缓存拦截器 cache-interceptor.ts
import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor,
  HttpResponse,
  HTTP_INTERCEPTORS
} from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { tap } from 'rxjs/operators';
import { ApiCacheService } from './api-cache.service';

// 替换为目标API域名规则
const CACHE_API_RULE = /^https:\/\/(公共API域名1|公共API域名2)\/.*/;

@Injectable()
export class CacheInterceptor implements HttpInterceptor {
  constructor(private cacheService: ApiCacheService) {}

  intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
    if (request.method !== 'GET' || !CACHE_API_RULE.test(request.url)) {
      return next.handle(request);
    }

    const cachedResponse = this.cacheService.get(request.url);
    if (cachedResponse) {
      return of(cachedResponse.clone());
    }

    return next.handle(request).pipe(
      tap(event => {
        if (event instanceof HttpResponse) {
          this.cacheService.set(request.url, event.clone());
        }
      })
    );
  }
}

// 3. AppModule 注册拦截器
@NgModule({
  providers: [
    { provide: HTTP_INTERCEPTORS, useClass: CacheInterceptor, multi: true }
  ]
})
export class AppModule {}

方案对比

  • Electron侧方案优势:无CORS限制、全局生效无需修改前端业务代码、缓存持久化实现简单,适合多窗口、多API需要统一管控缓存的场景
  • Angular侧方案优势:无需修改主进程代码、逻辑轻量化,适合仅少量接口需要缓存的小型项目

内容的提问来源于stack exchange,提问作者Mordred

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:48:00