React Native 展会图像缓存键功能

问题描述 投票:0回答:1

我正在尝试将 expo-image 包与预签名的 S3 图像一起使用。但是,即使我之前已经加载过图像,加载图像也需要几秒钟的时间。由于预签名 S3 URL 的动态特性,我将在第一个“?”处截断图像创建cacheKey,这应该为每个对象创建一个静态密钥。

我是否正确使用了cacheKey?考虑到显示图像需要多长时间,图像似乎没有被缓存。但是,当我打印出 onLoad 事件时,我可以看到“cacheType”:“disk”。

import { Image } from 'expo-image'
let uri = 'https://abcdefghi.s3.ap-southeast-1.amazonaws.com/152/message/myImageHere?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=XXXXXXXXXXXXXXXX%2F20231115%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Date=20231115T143523Z&X-Amz-Expires=432000&X-Amz-Signature=XXXXXXXXXXXXXXXXXXXXXXXX&X-Amz-SignedHeaders=host&x-id=GetObject'
<Image source={{ uri, cacheKey: uri.split('?')[0] }} />
react-native expo
1个回答
0
投票

Expo Image 不提供任何参数来手动设置缓存键。它使用媒体的 url 作为缓存键。由于 s3 预签名 URL 的动态特性,您的图像不会被缓存。这是一个示例网址:

https://presignedurldemo.s3.eu-west-2.amazonaws.com/image.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAJJWZ7B6WCRGMKFGQ%2F20180210%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20180210T171315Z&X-Amz-Expires=1800&X-Amz-Signature=12b74b0788aa036bc7c3d03b3f20c61f1f91cc9ad8873e3314255dc479a25351&X-Amz-SignedHeaders=host

始终使 url 唯一的一件事是

X-Amz-Date
参数,用于指示创建签名的日期和时间,格式为 YYYYMMDD'T'HHMMSS'Z'。这是 AWS Signature Version 4 签名流程的一部分,用于验证对 AWS 服务的请求。

X-Amz-Date
参数获取相同值(最多一周)的一个潜在解决方法是使用库
timekeeper
,它可以将系统时间冻结到所需的时间并欺骗 AWS。

这是从 s3 存储桶获取图像的示例代码。

import * as tk from 'timekeeper';
import {startOfWeek} from 'date-fns';
import {GetObjectCommand} from '@aws-sdk/client-s3';
import {getSignedUrl} from '@aws-sdk/s3-request-presigner';
import {S3Client} from '@aws-sdk/client-s3';

async function fetchThumbnailMedia(path: string) {
  const BUCKET = `dummy-dev`;
  const s3 = S3Client();

  const command = new GetObjectCommand({
    Bucket: BUCKET,
    Key: path,
    ResponseCacheControl: `public, max-age=604800, immutable`,
  });

  const startOfCurrentWeek = startOfWeek(new Date());
  tk.freeze(startOfCurrentWeek);

  const url = await getSignedUrl(s3, command, {
    expiresIn: 604800, // 7 days is the max time limit
  });

  tk.reset(); // Unfreeze time

  return url;
}

timekeeper.freeze
用于在为 S3 对象生成签名 URL 之前将系统时间冻结到本周的开始时间。这样做是为了确保签名 URL 中的
X-Amz-Date
参数在同一周始终相同,从而可以有效地缓存 URL。生成URL后,调用timekeeper.reset来解冻系统时间。

© www.soinside.com 2019 - 2024. All rights reserved.