jquery.cookie.js插件一个小bug

错误描述

极个别用户用IE浏览器访问页面,在加载页面的过程中,会出现如下错误提示:

错误分析

1、在页面使用jquery.cookie.js读cookie,加载页面时会查找cookie进行判断。

if(\$.cookie("resultDescription")!=null) {  
    _tips.html(\$.cookie("resultDescription")).show();  
    \$("#txtName").val(\$.cookie("userName"));  
    \$.cookie("resultDescription", null);  
    \$.cookie("userName", null);  
    \$(".tips-username").show();//显示忘记用户名  
   \$(".tips-ask").show();  
} 

2、jquery.cookie.js内部实现方式是根据key遍历查找header中所有的cookie,并对取到的值进行decodeURIComponent解码。

// key and possibly options given, get cookie...  
options = value || {};  
var decode = options.raw ? function(s) { return s; } : decodeURIComponent;  
var pairs = document.cookie.split('; ');  
for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {  
if (decode(pair[0]) === key) return decode(pair[1] || '');
 // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined  
} 

3、用户用ie浏览器访问该页面满足以下条件就会出现以上错误提示。

    1)用户浏览器中存在未知来源的cookie A(key=resultDescription,而value=被gb2312等编码过后的值)。

    2)A的domain属性(domain=”.123.com“)与我们站点相同(domain=”.123.com“),即我们是可以读到这个A的。

    在重现过程中发现好玩点:用户从FF浏览器访问页面,对于浏览器中存在其他域名所设定domain=”.123.com“的cookie是不会读取的,故没有任何错误,不过是xxx.123.com创建就可以访问了,故会出现错误了;

     用户用IE浏览器中只要浏览器存在domain=”.123.com“,无论是谁存入的都是直接访问的,不过体现就不一样的了。

重现问题如下(以下每步操作过后都是会清理cookie的):

protected void AddCookie_Click(object sender, EventArgs e)  
{  
HttpContext.Current.Response.Cookies.Add(new HttpCookie("resultDescription", HttpUtility.UrlEncode("中国", Encoding.GetEncoding("GB2312"))) 
{ Expires = DateTime.Now.AddDays(2),Domain = ".123.com"});  
Response.Redirect("https://xxx.123.com/");  
} 

解决方案

jquery.cookie.js本身是通过遍历header中的cookie来查找解码后的key对应的值,再对值解码,如果是读到的cookie本身是由该插件插入到浏览器的就没有问题,而我们并不排除有由后台插入的cookie被读到,故需要修改jquery.cookie.js文件的逻辑,在编码处增加try{}catch(e){}操作。

/*!
 * jQuery Cookie Plugin
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2011, Klaus Hartl
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.opensource.org/licenses/GPL-2.0
 */
(function ($) {
    $.cookie = function (key, value, options) {
        // key and at least value given, set cookie...
        if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) {
            options = $.extend({}, options);
            if (value === null || value === undefined) {
                options.expires = -1;
            }
            if (typeof options.expires === 'number') {
                var days = options.expires, t = options.expires = new Date();
                t.setDate(t.getDate() + days);
            }
            value = String(value);
            return (document.cookie = [
                encodeURIComponent(key), '=',
                options.raw ? value : encodeURIComponent(value),
                options.expires ? '; expires='+options.expires.toUTCString() : '',
                // use expires attribute, max-age is not supported by IE
                options.path ? '; path=' + options.path : '',
                options.domain ? '; domain=' + options.domain : '',
                options.secure ? '; secure' : ''
            ].join(''));
        }
        // key and possibly options given, get cookie...
        options = value || {};
        var decode = options.raw ? function (s) 
        { return s; } : decodeURIComponent;
        var pairs = document.cookie.split('; ');
        for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
            try {
            if (decode(pair[0]) === key) {                
                    var val = decode(pair[1] || '');
                    return val;
            } 
            // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined
            } catch (e) {

            }
        }
            
        return null;
    };
})(jQuery);
原文地址:https://www.cnblogs.com/jueye/p/2573067.html