mirror of
https://github.com/arthurfiorette/axios-cache-interceptor.git
synced 2025-12-08 17:36:16 +00:00
Update Cache-Control header to prevent caching (#1091)
This commit is contained in:
parent
3236cd3a10
commit
2c8910b848
1
.serena/.gitignore
vendored
Normal file
1
.serena/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/cache
|
||||
50
.serena/memories/code_style_conventions.md
Normal file
50
.serena/memories/code_style_conventions.md
Normal file
@ -0,0 +1,50 @@
|
||||
# Code Style and Conventions
|
||||
|
||||
## Language and Configuration
|
||||
|
||||
- **TypeScript**: Strict mode enabled with comprehensive type checking
|
||||
- **Module System**: ESNext with NodeNext module resolution
|
||||
- **Target**: ESNext for modern JavaScript features
|
||||
|
||||
## Code Quality Tools
|
||||
|
||||
- **Biome**: Used for linting, formatting, and code quality
|
||||
- Configuration extends `@arthurfiorette/biomejs-config`
|
||||
- Excludes build directories, dist, dev, coverage, node_modules
|
||||
- **TypeScript**: Strict configuration with all strict flags enabled
|
||||
|
||||
## TypeScript Configuration Highlights
|
||||
|
||||
- `strict: true` - All strict type checking enabled
|
||||
- `noImplicitAny: true`
|
||||
- `strictNullChecks: true`
|
||||
- `noUnusedLocals: true`
|
||||
- `noUnusedParameters: true`
|
||||
- `noImplicitReturns: true`
|
||||
- `noUncheckedIndexedAccess: true`
|
||||
- `verbatimModuleSyntax: true`
|
||||
|
||||
## File Structure Conventions
|
||||
|
||||
- Use `.ts` extensions for TypeScript files
|
||||
- Use `.js` extensions in import statements (for ESM compatibility)
|
||||
- Mirror test file structure with source files
|
||||
- Use kebab-case for file names when multiple words
|
||||
|
||||
## Import/Export Conventions
|
||||
|
||||
- Use named exports primarily
|
||||
- Main `index.ts` re-exports all public APIs
|
||||
- Use `.js` extensions in imports (transpiled to correct format)
|
||||
|
||||
## Development Build Support
|
||||
|
||||
- Uses `__ACI_DEV__` global constant for development-specific code
|
||||
- Development builds include console warnings
|
||||
- Production builds strip development code
|
||||
|
||||
## Code Organization
|
||||
|
||||
- Modular architecture with clear separation of concerns
|
||||
- Each module has its own directory with related types
|
||||
- Utilities are separated into dedicated util modules
|
||||
49
.serena/memories/codebase_structure.md
Normal file
49
.serena/memories/codebase_structure.md
Normal file
@ -0,0 +1,49 @@
|
||||
# Codebase Structure
|
||||
|
||||
## Root Directory
|
||||
|
||||
- `src/` - Main source code
|
||||
- `test/` - Test files (mirrors src structure)
|
||||
- `docs/` - VitePress documentation
|
||||
- `examples/` - Usage examples
|
||||
- `benchmark/` - Performance benchmarks
|
||||
- `build.sh` - Custom build script
|
||||
- `package.json` - Project configuration
|
||||
- `biome.json` - Code quality configuration
|
||||
- `tsconfig.json` - TypeScript configuration
|
||||
|
||||
## Source Code Structure (`src/`)
|
||||
|
||||
### Core Modules
|
||||
|
||||
- `index.ts` - Main entry point (exports all modules)
|
||||
- `cache/` - Core caching functionality
|
||||
- `axios.ts` - Axios integration
|
||||
- `cache.ts` - Cache implementation
|
||||
- `create.ts` - Cache creation utilities
|
||||
- `interceptors/` - Request/response interceptors
|
||||
- `request.ts` - Request interceptor logic
|
||||
- `response.ts` - Response interceptor logic
|
||||
- `build.ts` - Interceptor building utilities
|
||||
- `util.ts` - Interceptor utilities
|
||||
- `storage/` - Storage adapters
|
||||
- `memory.ts` - In-memory storage
|
||||
- `web-api.ts` - Web API storage (localStorage, etc.)
|
||||
- `build.ts` - Storage building utilities
|
||||
- `types.ts` - Storage type definitions
|
||||
- `header/` - HTTP header handling
|
||||
- `headers.ts` - Header utilities
|
||||
- `interpreter.ts` - Cache header interpretation
|
||||
- `types.ts` - Header type definitions
|
||||
- `util/` - General utilities
|
||||
- `cache-predicate.ts` - Cache condition checking
|
||||
- `key-generator.ts` - Cache key generation
|
||||
- `update-cache.ts` - Cache updating logic
|
||||
- `types.ts` - Utility type definitions
|
||||
|
||||
## Test Structure (`test/`)
|
||||
|
||||
- Mirrors the `src/` directory structure
|
||||
- Uses Node.js built-in test runner
|
||||
- Includes mock utilities in `test/mocks/`
|
||||
- Setup file: `test/setup.js`
|
||||
42
.serena/memories/project_overview.md
Normal file
42
.serena/memories/project_overview.md
Normal file
@ -0,0 +1,42 @@
|
||||
# Axios Cache Interceptor - Project Overview
|
||||
|
||||
## Purpose
|
||||
|
||||
Axios Cache Interceptor is a cache interceptor for axios designed with developers and performance in mind. It allows developers to call axios multiple times without worrying about overloading the network or implementing a simple and buggy cache system themselves.
|
||||
|
||||
## Key Features
|
||||
|
||||
- ⚡ Performance optimized
|
||||
- 📦 Multiple build targets (ESM, CJS, UMD)
|
||||
- 🔩 Easy to use - just wrap your axios instance
|
||||
- 🛠️ Rich caching features (ETags, Last-Modified, Cache-Control, etc.)
|
||||
- 🌐 Reduces network waste through intelligent caching
|
||||
- 🔑 Full TypeScript support
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- **Language**: TypeScript
|
||||
- **Package Manager**: pnpm (v9.1.1)
|
||||
- **Node Version**: >=12 (configured in .nvmrc)
|
||||
- **Build Tool**: microbundle (for multiple output formats)
|
||||
- **Code Quality**: Biome (linting, formatting, type checking)
|
||||
- **Testing**: Node.js built-in test runner with c8 for coverage
|
||||
- **Documentation**: VitePress
|
||||
|
||||
## Basic Usage
|
||||
|
||||
```ts
|
||||
import Axios from 'axios';
|
||||
import { setupCache } from 'axios-cache-interceptor';
|
||||
|
||||
const instance = Axios.create();
|
||||
const axios = setupCache(instance);
|
||||
|
||||
const req1 = axios.get('https://arthur.place/');
|
||||
const req2 = axios.get('https://arthur.place/');
|
||||
|
||||
const [res1, res2] = await Promise.all([req1, req2]);
|
||||
|
||||
res1.cached; // false
|
||||
res2.cached; // true
|
||||
```
|
||||
48
.serena/memories/suggested_commands.md
Normal file
48
.serena/memories/suggested_commands.md
Normal file
@ -0,0 +1,48 @@
|
||||
# Suggested Commands
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Code Quality
|
||||
|
||||
- `pnpm lint` - Check code quality with Biome
|
||||
- `pnpm lint-fix` - Fix code quality issues with Biome (including unsafe fixes)
|
||||
- `pnpm lint-ci` - Run linting for CI (strict mode)
|
||||
- `pnpm format` - Format code with Biome
|
||||
|
||||
### Testing
|
||||
|
||||
- `pnpm test` - Run all tests with coverage (using Node.js test runner + c8)
|
||||
- `pnpm test:only` - Run only tests marked with `test.only`
|
||||
- `pnpm test:types` - Run TypeScript type checking
|
||||
|
||||
### Building
|
||||
|
||||
- `pnpm build` - Build the project (runs build.sh script)
|
||||
- `bash build.sh` - Direct build script execution
|
||||
|
||||
### Documentation
|
||||
|
||||
- `pnpm docs:dev` - Start development documentation server (port 1227)
|
||||
- `pnpm docs:build` - Build documentation
|
||||
- `pnpm docs:serve` - Serve built documentation
|
||||
|
||||
### Other
|
||||
|
||||
- `pnpm benchmark` - Run performance benchmarks
|
||||
- `pnpm version` - Update version and changelog
|
||||
|
||||
## Build Outputs
|
||||
|
||||
- `dist/` - Production builds (multiple formats: ESM, CJS, Modern, UMD)
|
||||
- `dev/` - Development builds with debug information
|
||||
- Both include TypeScript declaration files
|
||||
|
||||
## Package Manager
|
||||
|
||||
- Uses **pnpm** as the package manager
|
||||
- Version: 9.1.1 (specified in packageManager field)
|
||||
|
||||
## Node Version
|
||||
|
||||
- Minimum: Node.js >=12
|
||||
- Uses `.nvmrc` for version specification
|
||||
37
.serena/memories/system_utilities.md
Normal file
37
.serena/memories/system_utilities.md
Normal file
@ -0,0 +1,37 @@
|
||||
# System Utilities and Environment
|
||||
|
||||
## System Information
|
||||
|
||||
- **Platform**: Linux
|
||||
- **OS**: Linux 5.15.133.1-microsoft-standard-WSL2 (WSL2 environment)
|
||||
- **Shell**: Bash
|
||||
|
||||
## Available System Commands
|
||||
|
||||
- `git` - Git version control
|
||||
- `ls` - List directory contents
|
||||
- `cd` - Change directory
|
||||
- `find` - Find files and directories
|
||||
- `grep` - Search text patterns
|
||||
- `bash` - Execute bash scripts
|
||||
- `node` - Node.js runtime
|
||||
- `pnpm` - Package manager
|
||||
|
||||
## Git Information
|
||||
|
||||
- **Current Branch**: arthurfiorette/safari-takeover
|
||||
- **Main Branch**: main (use for PRs)
|
||||
- **Status**: Clean working directory
|
||||
|
||||
## Project Environment
|
||||
|
||||
- **Working Directory**: /home/hzk/dev/axios-cache-interceptor
|
||||
- **Git Repository**: Yes
|
||||
- **Package Manager**: pnpm (version 9.1.1)
|
||||
- **Node Version**: >=12 (specified in package.json engines)
|
||||
|
||||
## Special Considerations for Linux/WSL2
|
||||
|
||||
- File permissions may need attention
|
||||
- Cross-platform compatibility is maintained in build scripts
|
||||
- Uses Unix-style line endings (`newLine: "lf"` in tsconfig)
|
||||
43
.serena/memories/task_completion_workflow.md
Normal file
43
.serena/memories/task_completion_workflow.md
Normal file
@ -0,0 +1,43 @@
|
||||
# Task Completion Workflow
|
||||
|
||||
## Commands to Run After Completing Tasks
|
||||
|
||||
### Code Quality Checks (Required)
|
||||
|
||||
1. `pnpm lint` - Check for linting issues
|
||||
2. `pnpm lint-fix` - Auto-fix linting issues (if needed)
|
||||
3. `pnpm test:types` - Verify TypeScript type checking passes
|
||||
|
||||
### Testing (Required)
|
||||
|
||||
4. `pnpm test` - Run all tests with coverage to ensure nothing is broken
|
||||
|
||||
### Build Verification (When Applicable)
|
||||
|
||||
5. `pnpm build` - Verify the build process works correctly (when changes affect build)
|
||||
|
||||
### Documentation (When Applicable)
|
||||
|
||||
6. `pnpm docs:build` - Verify documentation builds correctly (when docs are modified)
|
||||
|
||||
## Workflow Order
|
||||
|
||||
1. **First**: Fix any linting issues with `pnpm lint-fix`
|
||||
2. **Second**: Ensure types are correct with `pnpm test:types`
|
||||
3. **Third**: Run tests to verify functionality with `pnpm test`
|
||||
4. **Fourth**: Build if necessary with `pnpm build`
|
||||
5. **Finally**: Check documentation builds if docs were modified
|
||||
|
||||
## Pre-commit Considerations
|
||||
|
||||
- The project uses strict TypeScript configuration
|
||||
- All tests must pass
|
||||
- Code must pass linting
|
||||
- Type checking must pass
|
||||
- Build must succeed for production releases
|
||||
|
||||
## Development vs Production
|
||||
|
||||
- Development builds include debug information via `__ACI_DEV__` flag
|
||||
- Production builds strip debug code for optimal performance
|
||||
- Both are built simultaneously by the build script
|
||||
67
.serena/project.yml
Normal file
67
.serena/project.yml
Normal file
@ -0,0 +1,67 @@
|
||||
# language of the project (csharp, python, rust, java, typescript, go, cpp, or ruby)
|
||||
# * For C, use cpp
|
||||
# * For JavaScript, use typescript
|
||||
# Special requirements:
|
||||
# * csharp: Requires the presence of a .sln file in the project folder.
|
||||
language: typescript
|
||||
|
||||
# whether to use the project's gitignore file to ignore files
|
||||
# Added on 2025-04-07
|
||||
ignore_all_files_in_gitignore: true
|
||||
# list of additional paths to ignore
|
||||
# same syntax as gitignore, so you can use * and **
|
||||
# Was previously called `ignored_dirs`, please update your config if you are using that.
|
||||
# Added (renamed) on 2025-04-07
|
||||
ignored_paths: []
|
||||
|
||||
# whether the project is in read-only mode
|
||||
# If set to true, all editing tools will be disabled and attempts to use them will result in an error
|
||||
# Added on 2025-04-18
|
||||
read_only: false
|
||||
|
||||
# list of tool names to exclude. We recommend not excluding any tools, see the readme for more details.
|
||||
# Below is the complete list of tools for convenience.
|
||||
# To make sure you have the latest list of tools, and to view their descriptions,
|
||||
# execute `uv run scripts/print_tool_overview.py`.
|
||||
#
|
||||
# * `activate_project`: Activates a project by name.
|
||||
# * `check_onboarding_performed`: Checks whether project onboarding was already performed.
|
||||
# * `create_text_file`: Creates/overwrites a file in the project directory.
|
||||
# * `delete_lines`: Deletes a range of lines within a file.
|
||||
# * `delete_memory`: Deletes a memory from Serena's project-specific memory store.
|
||||
# * `execute_shell_command`: Executes a shell command.
|
||||
# * `find_referencing_code_snippets`: Finds code snippets in which the symbol at the given location is referenced.
|
||||
# * `find_referencing_symbols`: Finds symbols that reference the symbol at the given location (optionally filtered by type).
|
||||
# * `find_symbol`: Performs a global (or local) search for symbols with/containing a given name/substring (optionally filtered by type).
|
||||
# * `get_current_config`: Prints the current configuration of the agent, including the active and available projects, tools, contexts, and modes.
|
||||
# * `get_symbols_overview`: Gets an overview of the top-level symbols defined in a given file.
|
||||
# * `initial_instructions`: Gets the initial instructions for the current project.
|
||||
# Should only be used in settings where the system prompt cannot be set,
|
||||
# e.g. in clients you have no control over, like Claude Desktop.
|
||||
# * `insert_after_symbol`: Inserts content after the end of the definition of a given symbol.
|
||||
# * `insert_at_line`: Inserts content at a given line in a file.
|
||||
# * `insert_before_symbol`: Inserts content before the beginning of the definition of a given symbol.
|
||||
# * `list_dir`: Lists files and directories in the given directory (optionally with recursion).
|
||||
# * `list_memories`: Lists memories in Serena's project-specific memory store.
|
||||
# * `onboarding`: Performs onboarding (identifying the project structure and essential tasks, e.g. for testing or building).
|
||||
# * `prepare_for_new_conversation`: Provides instructions for preparing for a new conversation (in order to continue with the necessary context).
|
||||
# * `read_file`: Reads a file within the project directory.
|
||||
# * `read_memory`: Reads the memory with the given name from Serena's project-specific memory store.
|
||||
# * `remove_project`: Removes a project from the Serena configuration.
|
||||
# * `replace_lines`: Replaces a range of lines within a file with new content.
|
||||
# * `replace_symbol_body`: Replaces the full definition of a symbol.
|
||||
# * `restart_language_server`: Restarts the language server, may be necessary when edits not through Serena happen.
|
||||
# * `search_for_pattern`: Performs a search for a pattern in the project.
|
||||
# * `summarize_changes`: Provides instructions for summarizing the changes made to the codebase.
|
||||
# * `switch_modes`: Activates modes by providing a list of their names
|
||||
# * `think_about_collected_information`: Thinking tool for pondering the completeness of collected information.
|
||||
# * `think_about_task_adherence`: Thinking tool for determining whether the agent is still on track with the current task.
|
||||
# * `think_about_whether_you_are_done`: Thinking tool for determining whether the task is truly completed.
|
||||
# * `write_memory`: Writes a named memory (for future reference) to Serena's project-specific memory store.
|
||||
excluded_tools: []
|
||||
|
||||
# initial prompt for the project. It will always be given to the LLM upon activating the project
|
||||
# (contrary to the memories, which are loaded on demand).
|
||||
initial_prompt: ''
|
||||
|
||||
project_name: 'axios-cache-interceptor'
|
||||
@ -103,8 +103,7 @@ method for more information.
|
||||
- Type: `boolean`
|
||||
- Default: `true`
|
||||
|
||||
As most of our cache strategies depends on well known defined HTTP headers, most browsers
|
||||
also use those headers to define their own cache strategies and storages.
|
||||
As most of our cache strategies depend on well-known HTTP headers, most browsers also use those headers to define their own cache strategies and storages.
|
||||
|
||||
::: details This can be seen when opening network tab in your browser's dev tools.
|
||||
|
||||
@ -112,34 +111,50 @@ also use those headers to define their own cache strategies and storages.
|
||||
|
||||
:::
|
||||
|
||||
When your requested routes includes `Cache-Control` in their responses, you may end up
|
||||
with we and your browser caching the response, resulting in a **double layer of cache**.
|
||||
When your requested routes include `Cache-Control` in their responses, you may end up with both the library and your browser caching the response, resulting in a **double layer of cache**.
|
||||
|
||||
This option solves this by including some predefined headers in the request, that should
|
||||
tell any client / adapter to not cache the response, thus only we will cache it.
|
||||
This option solves this by including predefined headers in the request that instruct any client/adapter to not cache the response, thus ensuring only the library caches it.
|
||||
|
||||
**These are headers used in our specific request, it won't affect any other request or
|
||||
response that the server may handle.**
|
||||
**These headers are added to your specific request and won't affect any other request or response that the server may handle.**
|
||||
|
||||
Headers included:
|
||||
|
||||
- `Cache-Control: no-cache`
|
||||
- `Cache-Control: no-cache, no-store, must-revalidate`
|
||||
- `Pragma: no-cache`
|
||||
- `Expires: 0`
|
||||
|
||||
::: warning
|
||||
::: tip Alternative
|
||||
|
||||
This option will not work on most **CORS** requests, as the browser will throw
|
||||
`Request header field pragma is not allowed by Access-Control-Allow-Headers in preflight response.`.
|
||||
While `cacheTakeover` works for most browsers according to [this StackOverflow answer](https://stackoverflow.com/a/2068407), in some rare edge cases it may be unreliable due to browser-specific cache behaviors or network intermediaries.
|
||||
|
||||
When you encounter CORS error, you need to make sure `Cache-Control`, `Pragma` and
|
||||
`Expires` headers are included into your server's `Access-Control-Allow-Headers` CORS
|
||||
configuration.
|
||||
For maximum reliability, add a unique random query parameter instead:
|
||||
|
||||
If you cannot do such thing, you can fallback to disabling this option. Learn more on why
|
||||
it should be enabled at
|
||||
[#437](https://github.com/arthurfiorette/axios-cache-interceptor/issues/437#issuecomment-1361262194)
|
||||
and in this [StackOverflow](https://stackoverflow.com/a/62781874/14681561) answer.
|
||||
```ts
|
||||
axios.get(
|
||||
`/api/data?cachebuster=${Math.random().toString(36).slice(2)}`,
|
||||
{
|
||||
id: 'api-data-endpoint' // Keep same cache key despite different URLs
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
Your backend can ignore the `cachebuster` value. This **guarantees** no browser caching while preserving axios-cache-interceptor functionality.
|
||||
|
||||
:::
|
||||
|
||||
::: warning CORS Considerations
|
||||
|
||||
This option will not work on **CORS** requests with restricted headers, as the browser will throw:
|
||||
`Request header field Pragma is not allowed by Access-Control-Allow-Headers in preflight response.`
|
||||
|
||||
When you encounter CORS errors, you need to ensure `Cache-Control`, `Pragma`, and `Expires` headers are included in your server's `Access-Control-Allow-Headers` CORS configuration.
|
||||
|
||||
If you cannot modify the CORS configuration, you can:
|
||||
|
||||
1. Disable this option (`cacheTakeover: false`)
|
||||
2. Use the query parameter approach mentioned above
|
||||
|
||||
Learn more about why this should be enabled at [#437](https://github.com/arthurfiorette/axios-cache-interceptor/issues/437#issuecomment-1361262194) and in this [StackOverflow answer](https://stackoverflow.com/a/2068407).
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@ -99,8 +99,9 @@ export function defaultRequestInterceptor(axios: AxiosCacheInstance): RequestInt
|
||||
//
|
||||
// Its currently used before isMethodIn because if the isMethodIn returns false, the request
|
||||
// shouldn't be cached an therefore neither in the browser.
|
||||
// https://stackoverflow.com/a/2068407
|
||||
if (config.cache.cacheTakeover) {
|
||||
config.headers[Header.CacheControl] ??= 'no-cache';
|
||||
config.headers[Header.CacheControl] ??= 'no-cache, no-store, must-revalidate';
|
||||
config.headers[Header.Pragma] ??= 'no-cache';
|
||||
config.headers[Header.Expires] ??= '0';
|
||||
}
|
||||
|
||||
@ -366,7 +366,7 @@ describe('Request Interceptor', () => {
|
||||
const req1 = await axios.get('url');
|
||||
|
||||
assert.deepEqual(Object.assign({}, req1.request.config.headers), {
|
||||
[Header.CacheControl]: 'no-cache',
|
||||
[Header.CacheControl]: 'no-cache, no-store, must-revalidate',
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
'Content-Type': undefined,
|
||||
[Header.Pragma]: 'no-cache',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user