如何在JavaScript和Ruby on Rails中读取指定路径的Cookie?
Great question! Let’s break this down for both JavaScript and Ruby on Rails—yes, it is possible to read cookies scoped to a specific path, though the approach (and limitations) vary a bit between the two environments. First, a quick critical note: Cookies are restricted by their path attribute—a cookie with path /foo/bars is only accessible to pages/requests whose URL path starts with /foo/bars (e.g., /foo/bars or /foo/bars/detail). If your current page/request is outside that path (like /foo or /), the browser won’t expose the cookie at all—this is a core security rule for cookies.
JavaScript
Modern Approach: CookieStore API (Recommended)
The modern CookieStore API (supported in Chrome, Edge, Firefox 115+, and Safari 16.4+) lets you access full cookie metadata, including the path property. This makes filtering by path straightforward:
// Fetch all cookies accessible to the current page const allCookies = await cookieStore.getAll(); // Filter for the specific cookie by name and path const targetCookie = allCookies.find(cookie => { return cookie.name === 'some_key' && cookie.path === '/foo/bars'; }); if (targetCookie) { console.log('Cookie value:', targetCookie.value); } else { console.log('Cookie not found or inaccessible from this path'); }
Fallback for Older Browsers
Older browsers don’t support CookieStore, and document.cookie only returns key-value pairs (no path info). For these cases, you’ll need to either:
- Track the cookie’s path when you set it (store it in another cookie or a local variable), or
- Use a hacky verification method to confirm if a cookie belongs to your target path (note: this modifies and restores the cookie, so use carefully):
function getCookieByPath(name, targetPath) { // Split document.cookie into individual key-value pairs const cookiePairs = document.cookie.split(';').map(pair => pair.trim()); for (const pair of cookiePairs) { const [cookieName, cookieValue] = pair.split('='); if (cookieName !== name) continue; // Test if the cookie uses our target path by temporarily overwriting it const originalValue = cookieValue; document.cookie = `${name}=temp;path=${targetPath}`; // Check if the temporary value was applied const updatedPair = document.cookie.split(';') .find(p => p.trim().startsWith(`${name}=`)); // Restore the original cookie value document.cookie = `${name}=${originalValue};path=${targetPath}`; // If the temp value was set, the original cookie has our target path if (updatedPair?.trim() === `${name}=temp`) { return originalValue; } } return null; } // Usage const cookieValue = getCookieByPath('some_key', '/foo/bars'); console.log(cookieValue);
Ruby on Rails
In Rails, you can only access cookies that the browser sends with the current request (following the same path rules as JavaScript). The HTTP Cookie header only includes name-value pairs, not metadata like path—so Rails can’t directly read a cookie’s path from the request. Here’s how to handle this:
Reading Accessible Cookies
If your current request’s path is within the cookie’s path (e.g., request to /foo/bars/show for a cookie with path /foo/bars), the cookie will be available directly via the cookies hash:
# Returns the value of the cookie if it's accessible to the current request cookie_value = cookies[:some_key] puts cookie_value
If multiple cookies share the same name but have different paths, the browser will send the one with the most specific matching path—so cookies[:some_key] will return that value automatically.
Tracking Cookie Paths
Since Rails can’t get the cookie’s path from the request, if you need to confirm a cookie is associated with a specific path, you’ll need to store that info explicitly when setting the cookie:
- Option 1: Encode the path into the cookie value:
# When setting the cookie cookies[:some_key] = { value: "123|/foo/bars", # Encode value + path path: "/foo/bars" } # When reading, parse the value if cookies[:some_key] value, path = cookies[:some_key].split('|') if path == '/foo/bars' puts "Target cookie value: #{value}" end end - Option 2: Store the path in a separate cookie:
# When setting the cookie cookies[:some_key] = { value: 123, path: '/foo/bars' } cookies[:some_key_path] = { value: '/foo/bars', path: '/foo/bars' } # When reading, cross-reference the path cookie if cookies[:some_key_path] == '/foo/bars' puts "Cookie value: #{cookies[:some_key]}" end
内容的提问来源于stack exchange,提问作者Taichi

