PHP缓存功能实现求助:Google Drive文件本地缓存后无法下载
Hey there! Let's work through integrating that caching logic into your existing code to get your Google Drive file caching up and running properly. I'll break this down step by step with a concrete example:
Core Caching Logic Overview
The goal is straightforward:
- On the first request for File X, download it from Google Drive and save a copy to your server's local storage (our cache)
- For every subsequent request, skip the Drive download entirely and serve the local cached file directly
Step-by-Step Integration Example
Let's assume your original code (Code 1) is an Express.js endpoint handling Google Drive file downloads, and Code 2 contains cache checking/storage logic. Here's how to merge them seamlessly:
First, Define Our Base Components
We'll combine essential parts from both codebases with clear comments to track what's happening:
const express = require('express'); const axios = require('axios'); const fs = require('fs'); const path = require('path'); const app = express(); // -------------------------- // Cache Configuration (from Code 2) // -------------------------- const CACHE_DIR = './server-file-cache'; // Choose a directory for your cache const TARGET_FILE_NAME = 'file-x.pdf'; // Replace with your file's name/extension const GOOGLE_DRIVE_FILE_ID = 'YOUR_ACTUAL_FILE_ID'; // Get this from your Drive file's share link const GOOGLE_DRIVE_ACCESS_TOKEN = 'YOUR_ACTUAL_ACCESS_TOKEN'; // Valid Drive API token // Ensure the cache directory exists (create it if missing) if (!fs.existsSync(CACHE_DIR)) { fs.mkdirSync(CACHE_DIR, { recursive: true }); } // Check if the file exists in our local cache function checkLocalCache() { const cachedFilePath = path.join(CACHE_DIR, TARGET_FILE_NAME); return fs.existsSync(cachedFilePath) ? cachedFilePath : null; } // Save a downloaded file stream to the local cache async function saveToCache(fileStream) { const cachePath = path.join(CACHE_DIR, TARGET_FILE_NAME); const writeStream = fs.createWriteStream(cachePath); return new Promise((resolve, reject) => { fileStream.pipe(writeStream); writeStream.on('finish', () => resolve(cachePath)); writeStream.on('error', (err) => reject(err)); }); } // -------------------------- // Integrated Download Endpoint (Combined Code 1 + Code 2) // -------------------------- app.get('/download-file-x', async (req, res) => { try { // 1. First, check if we already have the file cached locally const cachedFile = checkLocalCache(); if (cachedFile) { console.log('✅ Serving file from local cache'); return res.sendFile(cachedFile); } // 2. Cache doesn't exist—download from Google Drive console.log('🔄 Downloading file from Google Drive (first request)...'); const driveResponse = await axios.get( `https://www.googleapis.com/drive/v3/files/${GOOGLE_DRIVE_FILE_ID}?alt=media`, { headers: { Authorization: `Bearer ${GOOGLE_DRIVE_ACCESS_TOKEN}` }, responseType: 'stream' // Critical: get the file as a stream to save and serve simultaneously } ); // 3. Save the stream to our cache while sending it to the user await saveToCache(driveResponse.data); driveResponse.data.pipe(res); console.log('✅ File downloaded and cached successfully'); } catch (error) { console.error('❌ Error processing request:', error.message); res.status(500).send('Failed to retrieve the file. Please try again later.'); } }); // Start the server app.listen(3000, () => { console.log('Server running on http://localhost:3000'); });
Key Things to Verify
- File Permissions: Make sure your server has read/write access to the
CACHE_DIRyou defined. If it can't write to the folder, caching will fail silently. - Drive API Setup: Double-check that your
GOOGLE_DRIVE_FILE_IDandACCESS_TOKENare correct. For server-side apps, use a service account token to avoid token expiration issues. - Cache Expiry (Optional): If the file on Google Drive might update, add logic to check the file's last modified time on Drive and refresh the cache when changes are detected.
- Error Handling: The example includes basic error handling, but you can expand it to handle cases like Drive API quota limits or cache write failures.
内容的提问来源于stack exchange,提问作者kaaris
相关产品推荐
相关产品推荐

