Safari 将垃圾写入 document.cookies 而不是非 ascii 字符

Safari writes trash to document.cookies instead non-ascii characters

我有下一段 javascript 代码:

wdata['account'] = {"value": $(input).val(), "title": "Номер карты получения"};
var r = {"ipayway": ipw_selected,
        "wpayway": wpw_selected,
        "amount_type": amount_type,
        "amount": amount,
        "email": email,
        "idata": idata,
        "wdata": wdata,
        "udata": udata
      }
console.log(JSON.stringify(r));
document.cookie = "r=" + JSON.stringify(r) + ";";
console.log(document.cookie);

在 chrome 和 firefox 中的调试结果:

{"ipayway":"3","wpayway":"2","amount_type":"invoice","amount":"10","email":"refer@faster.com","idata":{"phone":{"value":"79111111111","title":"phone"}},"wdata":{"account":{"value":"4444444444444448","title":"Номер карты получения"}},"udata":{}}

_ga=GA1.2.1726207989.1464355649; _ym_uid=1464355650833173718; _ym_isad=2; r%3Dfalse%3B; r={"ipayway":"3","wpayway":"2","amount_type":"invoice","amount":"10","email":"refer@faster.com","idata":{"phone":{"value":"79111111111","title":"phone"}},"wdata":{"account":{"value":"4444444444444448","title":"Номер карты получения"}},"udata":{}}; _gat=1; _ym_visorc_37606275=w

在 Safari 中:

{"ipayway":"3","wpayway":"2","amount_type":"invoice","amount":"10","email":"refer@faster.com","idata":{"phone":{"value":"79111111111","title":"phone"}},"wdata":{"account":{"value":"4444444444444448","title":"Номер карты получения"}},"udata":{}}


r={"ipayway":"3","wpayway":"2","amount_type":"invoice","amount":"10","email":"refer@faster.com","idata":{"phone":{"value":"79111111111","title":"phone"}},"wdata":{"account":{"value":"4444444444444448","title":"A1468837743323372246t%3A1468837754%3A; ga=GA1.2.1861993315.1468837742; gat=1; ym_isad=2; ym_uid=1468837743323372246; _ym_visorc_37606275=w

我不知道会发生什么。为什么 "title":"Номер карты получения" 就像在 chrome 或 firefox 中一样 我在 safari "title":"A1468837743323372246t%3A1468837754%3A 中得到了这个垃圾。如果您比较调试结果中的大括号,safari 也确实会切断最后一个闭合的大括号。

您需要在 HTML 元标记中添加 "charset=utf-8",并且 javascript。

<meta charset="utf-8">

<script type="text/javascript" charset="utf-8" src="/js/xxx.js"></script>

我在 Safari simply refuses to send any cookie containing non-ASCII characters that's why for cross-browsing need to use encodeURIComponent

找到了非常有用的信息

在我的例子中它将是:

wdata['account'] = {"value": $(input).val(), "title": encodeURIComponent("Номер карты получения")};
var r = {"ipayway": ipw_selected,
    "wpayway": wpw_selected,
    "amount_type": amount_type,
    "amount": amount,
    "email": email,
    "idata": idata,
    "wdata": wdata,
    "udata": udata
  }
document.cookie = "r=" + JSON.stringify(r) + ";

Cookie 将包含 title 值:%D0%9D%D0%BE%D0%BC%D0%B5%D1%80%20%D0%BA%D0%B0%D1%80%D1%82%D1%8B%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D1%8F,可以在后端轻松处理。例如 python:

import urllib
title = '%D0%9D%D0%BE%D0%BC%D0%B5%D1%80%20%D0%BA%D0%B0%D1%80%D1%82%D1%8B%20%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B5%D0%BD%D0%B8%D1%8F'
>>> print urllib.unquote(a)
Номер карты получения