WOU*_*nes 5 php cookies setcookie http-headers response-headers
这是来自较大应用程序的示例脚本,但显示了我正在尝试执行的操作的一般过程。如果我有以下脚本:
<?php
ob_start();
setcookie('test1', 'first');
setcookie('test1', 'second');
setcookie('test1', 'third');
setcookie('test2', 'keep');
//TODO remove duplicate test1 from headers
ob_end_clean();
die('end test');
Run Code Online (Sandbox Code Playgroud)
我得到以下响应(通过 Fiddler 查看):
HTTP/1.1 200 OK
Date: Tue, 25 Apr 2017 21:54:45 GMT
Server: Apache/2.4.17 (Win32) OpenSSL/1.0.2d PHP/5.5.30
X-Powered-By: PHP/5.5.30
Set-Cookie: test1=first
Set-Cookie: test1=second
Set-Cookie: test1=third
Set-Cookie: test2=keep
Content-Length: 8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
end test
Run Code Online (Sandbox Code Playgroud)
问题是Set-Cookie: test1......存在3次不同的时间,因此不必要地增加了标题大小。(同样,这是一个简化的示例 - 实际上,我正在处理 ~800 字节范围内的 ~10 个重复 cookie。)
有什么我可以写的东西来代替TODO完全摆脱标题的东西,或者它只显示一次?即以下是我的最终目标:
HTTP/1.1 200 OK
Date: Tue, 25 Apr 2017 21:54:45 GMT
Server: Apache/2.4.17 (Win32) OpenSSL/1.0.2d PHP/5.5.30
X-Powered-By: PHP/5.5.30
Set-Cookie: test1=third
Set-Cookie: test2=keep
Content-Length: 8
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html
end test
Run Code Online (Sandbox Code Playgroud)
虽然Set-Cookie: test1=third不可能存在,那很好,但Set-Cookie: test2=keep需要保留。当我尝试setcookie('test1', '', 1);删除 cookie 时,它会添加一个额外的标头以将其标记为已过期:
Set-Cookie: test1=first
Set-Cookie: test1=second
Set-Cookie: test1=third
Set-Cookie: test2=keep
Set-Cookie: test1=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0
Run Code Online (Sandbox Code Playgroud)
如果我尝试删除标题,如:
if (!headers_sent()) {
foreach (headers_list() as $header) {
if (stripos($header, 'Set-Cookie: test1') !== false) {
header_remove('Set-Cookie');
}
}
}
Run Code Online (Sandbox Code Playgroud)
Set-Cookie当我只想test1删除时,它会删除所有标题。
正如您在最后一段代码中所建议的那样,该headers_list()函数可用于检查已发送的标头。使用它,每个 cookie 的最后一个值可以存储在关联数组中。可以使用explode()(以及trim())提取名称和值。
当检测到多个具有相同名称的 cookie 时,我们可以header_remove()像您一样使用调用,然后将 cookie 设置为最终值。请参阅下面的示例以及此示例 phpfiddle。
if (!headers_sent()) {
$cookiesSet = []; //associative array to store the last value for each cookie
$rectifyCookies = false; //multiple values detected for same cookie name
foreach (headers_list() as $header) {
if (stripos($header, 'Set-Cookie:') !== false) {
list($setCookie, $cookieValue) = explode(':', $header);
list($cookieName, $cookieValue) = explode('=', trim($cookieValue));
if (array_key_exists($cookieName, $cookiesSet)) {
$rectifyCookies = true;
}
$cookiesSet[$cookieName] = $cookieValue;
}
}
if ($rectifyCookies) {
header_remove('Set-Cookie');
foreach($cookiesSet as $cookieName => $cookieValue) {
//might need to consider optional 3rd - 8th parameters
setcookie($cookieName, $cookieValue);
}
}
}
Run Code Online (Sandbox Code Playgroud)
Cache-Control max-age=0, no-cache, no-store, must-revalidate
Connection keep-alive
Content-Encoding gzip
Content-Type text/html; charset=utf-8
Date Wed, 26 Apr 2017 15:31:33 GMT
Expires Wed, 11 Jan 1984 05:00:00 GMT
Pragma no-cache
Server nginx
Set-Cookie test1=third
test2=keep
Transfer-Encoding chunked
Vary Accept -编码
| 归档时间: |
|
| 查看次数: |
4463 次 |
| 最近记录: |