快速免責聲明:當cookie被轉發到原始服務器時,CloudFront不僅緩存對URI和標題(以及查詢字符串,如果配置爲這樣做)的響應,還針對cookie的唯一組合由瀏覽器提供的值(或缺失的cookie) - 所以只有在緩存中包含(或缺少)完全相同的Cookie和值組合時才能從緩存中提供響應。這對您的緩存命中率沒有好處,但當然,它也是CloudFront的完全正確設計 - 如果提供了不同的Cookie,則CloudFront將無法選擇,只能認爲該Cookie可能會修改返回的響應從原點開始,所以Cookie必須成爲緩存鍵的組成部分。
它你必須轉發cookie,最好轉發特定的cookie。
然而,CloudFront的有一些是無關的緩存應用程序,所以有可能是有效的用例這樣的解決方案。
您的解決方案只會通過簡單和樂觀的測試。有很多邊緣情況下它不能正確處理。對於cookie的操作示例腳本只是一個簡單的例子,包括放棄的大意的東西:
* Header values are not parsed.
的第一個問題是,瀏覽器是免費的多個餅乾在一個Cookie:
頭結合,並且您對headers.cookie[i].value.indexOf(cookieName)
的測試不僅會與包含所需cookie的標頭相匹配,還會與包含該cookie的標頭以及其他 ...匹配,並刪除該特定標頭條目中的所有Cookie。
如果在查看器請求觸發器中使用,則使用此解決方案刪除太多Cookie的風險很大。在原始請求觸發器中,它甚至更高,因爲Cookie已被匹配的緩存行爲的cookie轉發配置剝離並重新規範化,並且CloudFront 確實在一個標題行上組合了多個Cookie,至少在某些條件。
的第二個問題是有關第一:indexOf()
簡單的字符串匹配將匹配cookie值,以及cookie名稱,因此有可能得到一個cookie 值錯誤匹配 - 這你不我想要檢查。
第三個問題是您沒有真正生成有效的重置值。 CloudFront似乎現在接受這一觀點,但由於技術上無效,未來有可能「固定」這種可能性。
我寫了一個Lambda @ Edge腳本,我相信它完全可以處理cookie語義,並且只會刪除您想要刪除的cookie,並且保持數據結構的清潔。因爲我認爲這是一個有趣的用例,所以我寫了它,以便它可以匹配儘可能多的Cookie,而不僅僅是一個cookie,只有cookie名稱上帶有精確字符串,區分大小寫的匹配項。
餅乾配置在靠近頂部的數組中。
在你的情況,有一個名爲__a_x_id
是這樣的cookie:
const discard = [ '__a_x_id' ];
添加多個cookie名稱的陣列將阻止他們。
這使用Node.js 6.10並與查看器請求觸發器或原始請求觸發器配合使用。如果您正在進行任何緩存,您可能需要將其用作原始請求觸發器,因爲這意味着它觸發的次數較少。
我也很高興地告訴大家,儘管看起來有點複雜,並且做了相當數量的字符串分割並且有多個嵌套循環,但是這個代碼在溫度容器中的Lambda執行時間始終小於1毫秒,是否有任何餅乾被匹配和刪除。
'use strict';
// source: https://stackoverflow.com/a/45970883/1695906
// iterate through all Cookie: headers in a request trigger,
// removing any cookies on the "discard" list, while preserving
// the integrity of any other cookies, including those appearing on the same
// header line, and confirm the resulting "cookie" array to CloudFront
// requirements by removing any now-empty elements, or the entire array
// if no cookies remain
// configure with one or more cookies to be removed from all requests;
// cookie names are case-sensitive
const discard = [ 'grover', 'big_bird' ]; // friends of cookie monster
exports.handler = (event, context, callback) => {
const request = event.Records[0].cf.request;
const headers = request.headers;
// does the request have any cookies? skip to the end, if not
if(headers.cookie)
{
const cookies = headers.cookie;
// iterate each Cookie: header, from last to first;
// last-to-first makes it simple to splice-out an array element
// because we then need not keep track of the reduced array length
for (var n = cookies.length; n--;)
{
// there may be multiple cookies per header line; examine them all
const cval = cookies[n].value.split(/;\ /);
const vlen = cval.length; // how many we started with
// check individual cookies on this line, backwards
for (var m = vlen; m--;)
{
// cookie name is to the left of "="
const cookie_kv = cval[m].split('=')[0];
// run though each member of "discard" array,
// removing the cookie if it's a match,
// again last to first but for no particular reason, here
for(var di = discard.length; di--;)
{
if(cookie_kv == discard[di])
{
cval.splice(m,1); // cookie removed!
break; // no need to check any other matches, already gone
}
}
} // for m
// if our array of cookies for this header line has now changed in size,
// we must have deleted some or all of it, so we need to reassemble
// what remains, or eliminate the entire line
if(cval.length != vlen)
{
if(cval.length === 0) // did we remove everything?
{
// yes? we can eliminate this entire line
cookies.splice(n,1);
}
else
{
// no? reassemble the remaining cookies
headers.cookie[n].value = cval.join('; ');
}
}
} // for n
// if the only cookies present in the request were cookies we removed,
// we now have a completely empty array in headers.cookie, which
// CloudFront should consider invalid; clean it up
if(cookies.length === 0)
{
delete headers.cookie;
}
}
// return control to CloudFront, possibly with our modified request
return callback(null, request);
};
您是否確實需要將**所有其他Cookie發送至原始地址?如果這是真的,你會得到很少的緩存命中。最好只發送特定的cookie(或者根本沒有cookie)。如果這真的是你需要的,請幫助我們理解這個cookie需要被刪除的原因,以便我們能夠提出最正確的解決方案。 –
Hi @ Michael-sqlbot我們不需要在CloudFront上緩存任何內容,我們的用例是使用CloudFront作爲代理網關。 –
爲了讓它跳躍而獲得讚譽......但是解決方案存在問題 - 它可能看起來有效,但操作標題時很重要;你寫的東西有一個隱藏的bug,因爲它可以隨意刪除* other * cookies,它實際上是生成一個無效的cookie頭,而不是乾淨地刪除你想阻止的那個。我開發了一個解決方案,在我能夠徹底測試它的預期和意外行爲後,我會提供這個解決方案。 –