乐闻世界logo
搜索文章和话题

How does Puppeteer manage cookies and storage? How to implement session persistence and multi-account management?

2月19日 19:39

Puppeteer provides powerful Cookie and storage management capabilities, allowing you to simulate real user sessions, maintain login states, and manage local storage.

1. Cookie Management

Get All Cookies:

javascript
const cookies = await page.cookies(); console.log(cookies);

Get Cookies for Specific URL:

javascript
const cookies = await page.cookies('https://example.com');

Set Cookie:

javascript
await page.setCookie({ name: 'session_id', value: 'abc123', domain: '.example.com', path: '/', expires: Math.floor(Date.now() / 1000) + 3600, // Expires in 1 hour httpOnly: true, secure: true, sameSite: 'Lax' });

Set Multiple Cookies:

javascript
await page.setCookie( { name: 'cookie1', value: 'value1', domain: '.example.com' }, { name: 'cookie2', value: 'value2', domain: '.example.com' } );

Delete Cookie:

javascript
// Delete specific cookie await page.deleteCookie({ name: 'session_id', domain: '.example.com' }); // Delete all cookies const cookies = await page.cookies(); await page.deleteCookie(...cookies);

Clear All Cookies:

javascript
await page.evaluate(() => { document.cookie.split(";").forEach(c => { document.cookie = c.replace(/^ +/, "").replace(/=.*/, "=;expires=" + new Date().toUTCString() + ";path=/"); }); });

2. LocalStorage Management

Get LocalStorage Data:

javascript
const localStorageData = await page.evaluate(() => { const data = {}; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); data[key] = localStorage.getItem(key); } return data; });

Set LocalStorage Data:

javascript
await page.evaluate(() => { localStorage.setItem('user_id', '12345'); localStorage.setItem('preferences', JSON.stringify({ theme: 'dark' })); });

Get Specific LocalStorage Item:

javascript
const userId = await page.evaluate(() => { return localStorage.getItem('user_id'); });

Delete LocalStorage Item:

javascript
await page.evaluate(() => { localStorage.removeItem('user_id'); });

Clear All LocalStorage:

javascript
await page.evaluate(() => { localStorage.clear(); });

3. SessionStorage Management

Get SessionStorage Data:

javascript
const sessionStorageData = await page.evaluate(() => { const data = {}; for (let i = 0; i < sessionStorage.length; i++) { const key = sessionStorage.key(i); data[key] = sessionStorage.getItem(key); } return data; });

Set SessionStorage Data:

javascript
await page.evaluate(() => { sessionStorage.setItem('temp_data', 'temporary_value'); });

Clear All SessionStorage:

javascript
await page.evaluate(() => { sessionStorage.clear(); });

4. IndexedDB Management

Get IndexedDB Data:

javascript
const indexedDBData = await page.evaluate(async () => { return new Promise((resolve, reject) => { const request = indexedDB.open('myDatabase', 1); request.onsuccess = (event) => { const db = event.target.result; const transaction = db.transaction(['myStore'], 'readonly'); const store = transaction.objectStore('myStore'); const getAllRequest = store.getAll(); getAllRequest.onsuccess = () => { resolve(getAllRequest.result); }; getAllRequest.onerror = () => { reject(getAllRequest.error); }; }; request.onerror = () => { reject(request.error); }; }); });

5. Browser Context and Isolation

Use Incognito Context:

javascript
const context = await browser.createIncognitoBrowserContext(); const page = await context.newPage(); // Operate in isolated environment await page.goto('https://example.com'); // Close context, clear all data await context.close();

Multiple Isolated Contexts:

javascript
// Create multiple isolated contexts const context1 = await browser.createIncognitoBrowserContext(); const context2 = await browser.createIncognitoBrowserContext(); const page1 = await context1.newPage(); const page2 = await context2.newPage(); // Cookies and storage are completely isolated between contexts

6. Session Persistence

Save Session State:

javascript
async function saveSession(page, filePath) { const cookies = await page.cookies(); const localStorage = await page.evaluate(() => { const data = {}; for (let i = 0; i < localStorage.length; i++) { const key = localStorage.key(i); data[key] = localStorage.getItem(key); } return data; }); const session = { cookies, localStorage, url: page.url(), timestamp: Date.now() }; const fs = require('fs'); fs.writeFileSync(filePath, JSON.stringify(session, null, 2)); }

Restore Session State:

javascript
async function restoreSession(page, filePath) { const fs = require('fs'); const session = JSON.parse(fs.readFileSync(filePath, 'utf8')); // Restore cookies await page.setCookie(...session.cookies); // Restore localStorage await page.evaluate((data) => { for (const [key, value] of Object.entries(data)) { localStorage.setItem(key, value); } }, session.localStorage); // Navigate to previous URL await page.goto(session.url); }

7. Practical Use Cases

Use Case 1: Maintain Login State

javascript
async function loginAndSaveSession() { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Login await page.goto('https://example.com/login'); await page.type('#username', 'user@example.com'); await page.type('#password', 'password'); await page.click('#login-button'); await page.waitForNavigation(); // Save session await saveSession(page, 'session.json'); await browser.close(); } async function useSavedSession() { const browser = await puppeteer.launch(); const page = await browser.newPage(); // Restore session await restoreSession(page, 'session.json'); // Access pages requiring login directly await page.goto('https://example.com/dashboard'); // Verify logged in const isLoggedIn = await page.$('.user-profile') !== null; console.log('Is logged in:', isLoggedIn); await browser.close(); }

Use Case 2: Multi-Account Management

javascript
async function manageMultipleAccounts(accounts) { const browser = await puppeteer.launch(); for (const account of accounts) { // Create isolated context for each account const context = await browser.createIncognitoBrowserContext(); const page = await context.newPage(); // Login account await page.goto('https://example.com/login'); await page.type('#username', account.username); await page.type('#password', account.password); await page.click('#login-button'); await page.waitForNavigation(); // Perform account operations await page.goto('https://example.com/dashboard'); const data = await page.evaluate(() => { return document.querySelector('.user-data').textContent; }); console.log(`Account ${account.username}: ${data}`); // Close context, clear data await context.close(); } await browser.close(); } manageMultipleAccounts([ { username: 'user1@example.com', password: 'pass1' }, { username: 'user2@example.com', password: 'pass2' } ]);

Use Case 3: A/B Testing

javascript
async function abTesting(url, variants) { const browser = await puppeteer.launch(); for (const variant of variants) { const context = await browser.createIncognitoBrowserContext(); const page = await context.newPage(); // Set A/B test cookie await page.setCookie({ name: 'ab_test_variant', value: variant.id, domain: new URL(url).hostname }); await page.goto(url); // Collect data const data = await page.evaluate(() => { return { title: document.title, content: document.querySelector('.content')?.textContent }; }); console.log(`Variant ${variant.id}:`, data); await context.close(); } await browser.close(); } abTesting('https://example.com', [ { id: 'A' }, { id: 'B' } ]);

Use Case 4: Shopping Cart Persistence

javascript
async function saveShoppingCart(page, userId) { const cartData = await page.evaluate(() => { return JSON.parse(localStorage.getItem('cart') || '[]'); }); const fs = require('fs'); const filePath = `carts/${userId}.json`; fs.writeFileSync(filePath, JSON.stringify(cartData, null, 2)); } async function restoreShoppingCart(page, userId) { const fs = require('fs'); const filePath = `carts/${userId}.json`; if (fs.existsSync(filePath)) { const cartData = JSON.parse(fs.readFileSync(filePath, 'utf8')); await page.evaluate((data) => { localStorage.setItem('cart', JSON.stringify(data)); }, cartData); } }

8. Security Considerations

1. Sensitive Data Protection:

javascript
// Don't hardcode sensitive information in code // Use environment variables const password = process.env.PASSWORD; // Don't commit session files containing sensitive info to version control // Add session.json to .gitignore

2. Cookie Security:

javascript
// Set secure cookie attributes await page.setCookie({ name: 'session', value: 'value', httpOnly: true, // Prevent XSS attacks secure: true, // Only transmit over HTTPS sameSite: 'Strict' // Prevent CSRF attacks });

3. Session Expiration Handling:

javascript
async function checkSessionValidity(page) { const cookies = await page.cookies(); const sessionCookie = cookies.find(c => c.name === 'session_id'); if (!sessionCookie || sessionCookie.expires * 1000 < Date.now()) { // Session expired, re-login await relogin(page); } }

9. Best Practices

1. Use Isolated Contexts:

javascript
// Create isolated context for each user or session const context = await browser.createIncognitoBrowserContext(); const page = await context.newPage(); // Close context after operations await context.close();

2. Regular Cleanup:

javascript
// Regularly clean expired cookies and storage async function cleanupStorage(page) { const cookies = await page.cookies(); const validCookies = cookies.filter(c => !c.expires || c.expires * 1000 > Date.now() ); await page.deleteCookie(...cookies); await page.setCookie(...validCookies); }

3. Error Handling:

javascript
try { await page.setCookie(cookie); } catch (error) { console.error('Failed to set cookie:', error); // Handle error }

4. Performance Optimization:

javascript
// Batch cookie operations await page.setCookie(...cookies); // Avoid frequent storage operations const data = await page.evaluate(() => { // Get all needed data at once return { localStorage: { ...localStorage }, sessionStorage: { ...sessionStorage } }; });
标签:Puppeteer