tomcat下的Cookie特殊符號問題


案例:
在項目中通過Cookie方式臨時存放檢索條件,不小心在Cookie值中使用了特殊符號"@",導致在服務器端無法正確解析Cookie值。
之所以說"不小心",根本原因是對於Cookie的理解不夠深入。
實際上在開發環境使用run-jetty-run插件進行調試時並未發現問題,經驗證:
在jetty下可以在Cookie中使用特殊符號@,但是在Tomcat下不能在Cookie中使用特殊符號@。

Cookie規范經歷了多個版本發展,分別是: RFC 2109(1997年),RFC 2965(2000年), RFC 6265(2011年)。
Cookie值的約定見rfc2068描述(https://tools.ietf.org/html/rfc2068):

Many HTTP/1.1 header field values consist of words separated by LWS
or special characters. These special characters MUST be in a quoted
string to be used within a parameter value.

      token          = 1*<any CHAR except CTLs or tspecials>

      tspecials      = "(" | ")" | "<" | ">" | "@"
                     | "," | ";" | ":" | "\" | <">
                     | "/" | "[" | "]" | "?" | "="
                     | "{" | "}" | SP | HT

對應的,在Tomcat實現中javax.servlet.http.Cookie對特殊字符的定義如下:

class RFC6265Validator extends CookieNameValidator {
    private static final String RFC2616_SEPARATORS = "()<>@,;:\\\"/[]?={} \t";

    RFC6265Validator() {
        super(RFC2616_SEPARATORS);
    }
}

顯然,相應特殊字符在Tomcat下不要在Cookie中使用,否則會導致Tomcat無法正確解析Cookie信息。
而跟蹤jetty源碼發現,org.eclipse.jetty.server.CookieCutter方法parseFields()並不會把Cookie中的"@"作為特殊字符過濾掉。

總結:
雖然在jetty中僥幸可以使用特殊字符@作為Cookie值,但是建議在Cookie中不要使用任何特殊字符,否則應用程序的移植性太差。
而且,對於存儲的Cookie,最好進行編碼處理。如通過escape()方法對Cookie進行編碼:

function setCookie(c_name,value,expiredays) {
    var exdate = new Date();
    exdate.setDate(exdate.getDate() + expiredays);
    document.cookie=c_name + "=" + escape(value)+ ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
}


【參考】
https://en.wikipedia.org/wiki/HTTP_cookie
https://tools.ietf.org/html/rfc2109
https://tools.ietf.org/html/rfc2965
https://tools.ietf.org/html/rfc6265
http://www.blogjava.net/stone2083/archive/2010/11/03/336923.html  關於cookie特殊字符的一點理解
https://www.biaodianfu.com/cookie-symbol.html  Cookie與特殊字符

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM