如何在 cookie 中安全地存储 Unicode 字符?
How to safely store Unicode characters in cookies?
我正在使用 cookie 在搜索页面中显示一些数据,但我的 cookie 在使用 Unicode 字符时会混淆值。例如,当我存储 Inglês
时,当我读回它时我得到 Inglês
。
这是我保存 cookie 的方式:
public void SalvaValue(string sessionKey, string sessionValue)
{
Response.Cookies.Add(new HttpCookie(sessionKey));
var httpCookie = Response.Cookies[sessionKey];
if (httpCookie != null) httpCookie.Value = sessionValue;
if (httpCookie != null) httpCookie.Expires = DateTime.Now.AddDays(14);
}
这是我检索它的方式:
if (Request.Cookies["BuscaTipo"] != null)
{
tipoBusca = Request.Cookies["BuscaTipo"].Value.ToString();
var cookie = new HttpCookie("BuscaTipo") { Expires = DateTime.Now.AddDays(-1) };
Response.Cookies.Add(cookie);
}
当我调试网站时,它在代码中显示了正确的设置值,但在我使用 jQuery 执行请求后,该值出现了错误的字符。
如何在 cookie 中安全地存储 Unicode 字符?
请参阅 How to store other languages (unicode) in cookies and get it back again, Unicode Cookie Value, How to send non-English unicode string using HTTP header? and Allowed characters in cookies 了解为什么需要对 cookie 值进行编码的解释。
简而言之:大多数浏览器都支持 headers(其中发送 cookie)中的 Unicode 字符,但并非所有浏览器都支持。一些浏览器将 Unicode 字节解释为 ASCII,导致 Mojibake。
jQuery 似乎也根据一些链接问题发挥作用,但我无法重现。
因此,要在所有浏览器中安全地存储 Unicode 字符(或任何 non-ASCII 或控制字符),您需要对字符进行编码。这可以通过例如 base64 和 percent-encoding 来实现。
后者的实现,略微改编自Cookies and Unicode characters:
public static class CookieExtensions
{
public static string DecodedValue(this HttpCookie cookie)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
return HttpUtility.UrlDecode(cookie.Value);
}
public static void SetEncodedValue(this HttpCookie cookie, string value)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
cookie.Value = HttpUtility.UrlEncode(value);
}
public static string DecodedValues(this HttpCookie cookie, string name)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
return HttpUtility.UrlDecode(cookie.Values[name]);
}
public static void SetEncodedValues(this HttpCookie cookie, string name, string value)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
cookie.Values[name] = HttpUtility.UrlEncode(value);
}
public static string DecodedValues(this HttpCookie cookie, int index)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
return HttpUtility.UrlDecode(cookie.Values[index]);
}
}
用法:
if (Request.Cookies["TestCookieValue"] != null)
{
ViewBag.CookieValue = Request.Cookies["TestCookieValue"].DecodedValue();
}
if (Request.Cookies["TestCookieValues"] != null)
{
ViewBag.CookieValues = Request.Cookies["TestCookieValues"].DecodedValues("foo");
ViewBag.CookieValuesIndexed = Request.Cookies["TestCookieValues"].DecodedValues(0);
}
var cookieWithValue = new HttpCookie("TestCookieValue");
cookieWithValue.Expires = DateTime.Now.AddHours(1);
cookieWithValue.SetEncodedValue("Inglês");
Response.SetCookie(cookieWithValue);
var cookieWithValues = new HttpCookie("TestCookieValues");
cookieWithValues.Expires = DateTime.Now.AddHours(1);
cookieWithValues.SetEncodedValues("foo", "Inglês");
Response.SetCookie(cookieWithValues);
请注意 HttpUtility.UrlDecode()
is dangerous, use AntiXSS 以防止 Cross-site 脚本和 SQL 从 cookie 值注入,这可以由客户端任意设置。
您也可以重新考虑在 cookie 中存储 Unicode 值。您可以通过其他方式轻松识别语言,例如通过代码 en-US
或其数据库索引(如果适用)。
我正在使用 cookie 在搜索页面中显示一些数据,但我的 cookie 在使用 Unicode 字符时会混淆值。例如,当我存储 Inglês
时,当我读回它时我得到 Inglês
。
这是我保存 cookie 的方式:
public void SalvaValue(string sessionKey, string sessionValue)
{
Response.Cookies.Add(new HttpCookie(sessionKey));
var httpCookie = Response.Cookies[sessionKey];
if (httpCookie != null) httpCookie.Value = sessionValue;
if (httpCookie != null) httpCookie.Expires = DateTime.Now.AddDays(14);
}
这是我检索它的方式:
if (Request.Cookies["BuscaTipo"] != null)
{
tipoBusca = Request.Cookies["BuscaTipo"].Value.ToString();
var cookie = new HttpCookie("BuscaTipo") { Expires = DateTime.Now.AddDays(-1) };
Response.Cookies.Add(cookie);
}
当我调试网站时,它在代码中显示了正确的设置值,但在我使用 jQuery 执行请求后,该值出现了错误的字符。
如何在 cookie 中安全地存储 Unicode 字符?
请参阅 How to store other languages (unicode) in cookies and get it back again, Unicode Cookie Value, How to send non-English unicode string using HTTP header? and Allowed characters in cookies 了解为什么需要对 cookie 值进行编码的解释。
简而言之:大多数浏览器都支持 headers(其中发送 cookie)中的 Unicode 字符,但并非所有浏览器都支持。一些浏览器将 Unicode 字节解释为 ASCII,导致 Mojibake。
jQuery 似乎也根据一些链接问题发挥作用,但我无法重现。
因此,要在所有浏览器中安全地存储 Unicode 字符(或任何 non-ASCII 或控制字符),您需要对字符进行编码。这可以通过例如 base64 和 percent-encoding 来实现。
后者的实现,略微改编自Cookies and Unicode characters:
public static class CookieExtensions
{
public static string DecodedValue(this HttpCookie cookie)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
return HttpUtility.UrlDecode(cookie.Value);
}
public static void SetEncodedValue(this HttpCookie cookie, string value)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
cookie.Value = HttpUtility.UrlEncode(value);
}
public static string DecodedValues(this HttpCookie cookie, string name)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
return HttpUtility.UrlDecode(cookie.Values[name]);
}
public static void SetEncodedValues(this HttpCookie cookie, string name, string value)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
cookie.Values[name] = HttpUtility.UrlEncode(value);
}
public static string DecodedValues(this HttpCookie cookie, int index)
{
if (cookie == null)
{
throw new ArgumentNullException("cookie");
}
return HttpUtility.UrlDecode(cookie.Values[index]);
}
}
用法:
if (Request.Cookies["TestCookieValue"] != null)
{
ViewBag.CookieValue = Request.Cookies["TestCookieValue"].DecodedValue();
}
if (Request.Cookies["TestCookieValues"] != null)
{
ViewBag.CookieValues = Request.Cookies["TestCookieValues"].DecodedValues("foo");
ViewBag.CookieValuesIndexed = Request.Cookies["TestCookieValues"].DecodedValues(0);
}
var cookieWithValue = new HttpCookie("TestCookieValue");
cookieWithValue.Expires = DateTime.Now.AddHours(1);
cookieWithValue.SetEncodedValue("Inglês");
Response.SetCookie(cookieWithValue);
var cookieWithValues = new HttpCookie("TestCookieValues");
cookieWithValues.Expires = DateTime.Now.AddHours(1);
cookieWithValues.SetEncodedValues("foo", "Inglês");
Response.SetCookie(cookieWithValues);
请注意 HttpUtility.UrlDecode()
is dangerous, use AntiXSS 以防止 Cross-site 脚本和 SQL 从 cookie 值注入,这可以由客户端任意设置。
您也可以重新考虑在 cookie 中存储 Unicode 值。您可以通过其他方式轻松识别语言,例如通过代码 en-US
或其数据库索引(如果适用)。