JSON.parse(JSON.stringify(e)) 将对象转换为字符串

JSON.parse(JSON.stringify(e)) converts object to a string

我们正在将 onetrust cookie 同意脚本集成到 TYPO3 网站中。在另一个 CMS 运行 的子页面上,它可以工作,但在主页面上却没有。

我追查到这个问题,onetrust 使用 JSON.parse(JSON.stringify(e)) 克隆一个对象。我读到这是一种不好的做法,但我无法更改该代码。

归结为 - 所以在字符串化和解析之后类型发生了变化。

typeof e.Groups 
"object"
typeof JSON.parse(JSON.stringify(e)).Groups
"string"

我正在 Chrome 72

测试

这是 JSON.stringify(e.Groups) 的输出(e.Groups 是一个对象,但这看起来像是字符串的字符串化版本)

"[{\"ShowInPopup\": true, \"Order\": \"1\", \"OptanonGroupId\": \"C0001\", \"Parent\": \"\", \"ShowSubgroup\": true, \"ShowSubGroupDescription\": true, \"ShowSubgroupToggle\": false, \"GroupDescription\": \"Diese Cookies sind zur Funktion der Website erforderlich und können in Ihren Systemen nicht deaktiviert werden. In der Regel werden diese Cookies nur als Reaktion auf von Ihnen getätigte Aktionen gesetzt, die einer Dienstanforderung entsprechen, wie etwa dem Festlegen Ihrer Datenschutzeinstellungen, dem Anmelden oder dem Ausfüllen von Formularen. Sie können Ihren Browser so einstellen, dass diese Cookies blockiert oder Sie über diese Cookies benachrichtigt werden. Einige Bereiche der Website funktionieren dann aber nicht. Diese Cookies speichern keine personenbezogenen Daten.\", \"GroupName\": \"Essentiell\", \"IsIabPurpose\": false, \"FirstPartyCookies\": [{\"Name\": \"mage-translation-file-version\", \"Host\": \"dealer.stage.example.com\", \"IsSession\": true, \"Length\": \"0\", \"description\": \"\"}, {\"Name\": \"OptanonConsent\", \"Host\": \".custom.example.com\", \"IsSession\": false, \"Length\": \"365\", \"description\": \"This cookie is set by the cookie compliance solution from OneTrust. It stores information about the categories of cookies the site uses and whether visitors have given or withdrawn consent for the use of each category. This enables site owners to prevent cookies in each category from being set in the users browser, when consent is not given. The cookie has a normal lifespan of one year, so that returning visitors to the site will have their preferences remembered. It contains no information that can identify the site visitor.\"}, {\"Name\": \"mage-cache-storage-section-invalidation\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"1\", \"description\": \"This cookie is used to facilitate content caching on the browser to make pages load faster.\n\"}, {\"Name\": \"magepal-enhanced-ecommerce\", \"Host\": \"www.example.com\", \"IsSession\": true, \"Length\": \"0\", \"description\": \"\"}, {\"Name\": \"OptanonAlertBoxClosed\", \"Host\": \".www.example.com\", \"IsSession\": false, \"Length\": \"365\", \"description\": \"This cookie is set by websites using certain versions of the cookie law compliance solution from OneTrust.  It is set after visitors have seen a cookie information notice and in some cases only when they actively close the notice down.  It enables the website not to show the message more than once to a user.  The cookie has a one year lifespan and contains no personal information.\"}, {\"Name\": \"mage-translation-storage\", \"Host\": \"www.example.com\", \"IsSession\": true, \"Length\": \"0\", \"description\": \"This cookie is used to facilitate content caching on the browser to make pages load faster.\n\"}, {\"Name\": \"mage-cache-sessid\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"1\", \"description\": \"\"}, {\"Name\": \"geoIpRedirected\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"365\", \"description\": \"\"}, {\"Name\": \"mage-cache-storage\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"1\", \"description\": \"This cookie is used to facilitate content caching on the browser to make pages load faster.\n\"}, {\"Name\": \"PHPSESSID\", \"Host\": \"www.example.com\", \"IsSession\": true, \"Length\": \"0\", \"description\": \"Cookie generated by applications based on the PHP language.  This is a general purpose identifier used to maintain user session variables. It is normally a random generated number, how it is used can be specific to the site, but a good example is maintaining a logged-in status for a user between pages.\"}, {\"Name\": \"mage-messages\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"1\", \"description\": \"\"}, {\"Name\": \"form_key\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"0\", \"description\": \"This cookie is used to facilitate content caching on the browser to make pages load faster.\n\"}], \"Hosts\": [], \"PurposeId\": \"\", \"CustomGroupId\": \"C0001\", \"GroupId\": \"6593bfda-c8d7-4b34-862a-fdb39a0e482f\", \"Status\": \"always active\", \"IsDntEnabled\": false}, {\"ShowInPopup\": true, \"Order\": \"2\", \"OptanonGroupId\": \"C0003\", \"Parent\": \"\", \"ShowSubgroup\": true, \"ShowSubGroupDescription\": true, \"ShowSubgroupToggle\": false, \"GroupDescription\": \"Mit diesen Cookies ist die Website in der Lage, erweiterte Funktionalität und Personalisierung bereitzustellen. Sie können von uns oder von Drittanbietern gesetzt werden, deren Dienste wir auf unseren Seiten verwenden. Wenn Sie diese Cookies nicht zulassen, funktionieren einige oder alle dieser Dienste möglicherweise nicht einwandfrei.\", \"GroupName\": \"Funktionelle Cookies\", \"IsIabPurpose\": false, \"FirstPartyCookies\": [{\"Name\": \"fe_typo_user\", \"Host\": \".example.com\", \"IsSession\": true, \"Length\": \"0\", \"description\": \"This cookie name is associated with the Typo3 web content management system.  It is generally used as a user session identifier to enable user preferences to be stored, but in many cases it may not actually be needed as it can be set by defualt by the platform, though this can be prevented by site administrators.  In most cases it is set to be destroyed at the end of a browser session. It contains a random identifier rather than any specific user data.\"}, {\"Name\": \"section_data_ids\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"1\", \"description\": \"This cookie is used to facilitate content caching on the browser to make pages load faster.\n\"}, {\"Name\": \"private_content_version\", \"Host\": \"www.example.com\", \"IsSession\": false, \"Length\": \"3650\", \"description\": \"This cookie is used to facilitate content caching on the browser to make pages load faster.\n\"}], \"Hosts\": [{\"HostName\": \"player.video.com\", \"HostId\": \"dpy\", \"Description\": \"\", \"Cookies\": [{\"Name\": \"muxData\", \"Host\": \"player.video.com\", \"IsSession\": false, \"Length\": \"365\", \"description\": \"\"}]}], \"PurposeId\": \"\", \"CustomGroupId\": \"C0003\", \"GroupId\": \"c85d4f6a-e269-4049-b6a0-2dfd812d80bd\", \"Status\": \"always active\", \"IsDntEnabled\": false}, {\"ShowInPopup\": true, \"Order\": \"3\", \"OptanonGroupId\": \"C0002\", \"Parent\": \"\", \"ShowSubgroup\": true, \"ShowSubGroupDescription\": true, \"ShowSubgroupToggle\": false, \"GroupDescription\": \"Diese Cookies ermöglichen es uns, Besuche und Verkehrsquellen zu zählen, damit wir die Leistung unserer Website messen und verbessern können. Sie unterstützen uns bei der Beantwortung der Fragen, welche Seiten am beliebtesten sind, welche am wenigsten genutzt werden und wie sich Besucher auf der Website bewegen. Alle von diesen Cookies erfassten Informationen werden aggregiert und sind deshalb anonym. Wenn Sie diese Cookies nicht zulassen, können wir nicht wissen, wann Sie unsere Website besucht haben.\", \"GroupName\": \"Analytics\", \"IsIabPurpose\": false, \"FirstPartyCookies\": [{\"Name\": \"_ga\", \"Host\": \".example.com\", \"IsSession\": false, \"Length\": \"365\", \"description\": \"This cookie name is asssociated with Google Universal Analytics - which is a significant update to Google's more commonly used analytics service. This cookie is used to distinguish unique users by assigning a randomly generated number as a client identifier. It is included in each page request in a site and used to calculate visitor, session and campaign data for the sites analytics reports.  By default it is set to expire after 2 years, although this is customisable by website owners.\"}, {\"Name\": \"_gat_UA-nnnnnnn-nn\", \"Host\": \"example.com\", \"IsSession\": false, \"Length\": \"0\", \"description\": \"This is a pattern type cookie set by Google Analytics, where the pattern element on the name contains the unique identity number of the account or website it relates to. It appears to be a variation of the _gat cookie which is used to limit the amount of data recorded by Google on high traffic volume websites.\"}, {\"Name\": \"_gid\", \"Host\": \".example.com\", \"IsSession\": false, \"Length\": \"1\", \"description\": \"This cookie name is asssociated with Google Universal Analytics. This appears to be a new cookie and as of Spring 2017 no information is available from Google.  It appears to store and update a unique value for each page visited.\"}, {\"Name\": \"_gcl_au\", \"Host\": \".example.com\", \"IsSession\": false, \"Length\": \"90\", \"description\": \"Used by Google AdSense for experimenting with advertisement efficiency across websites using their services\"}], \"Hosts\": [{\"HostName\": \"nr-data.net\", \"HostId\": \"jzl\", \"Description\": \"\", \"Cookies\": [{\"Name\": \"JSESSIONID\", \"Host\": \"nr-data.net\", \"IsSession\": true, \"Length\": \"0\", \"description\": \"This domain is controlled by New Relic, which provides a platform for monitoring the performance of web and mobile applications.\"}]}], \"PurposeId\": \"\", \"CustomGroupId\": \"C0002\", \"GroupId\": \"e2032e4c-31e2-4106-9f81-041989913a21\", \"Status\": \"inactive\", \"IsDntEnabled\": false}, {\"ShowInPopup\": true, \"Order\": \"4\", \"OptanonGroupId\": \"C0005\", \"Parent\": \"\", \"ShowSubgroup\": true, \"ShowSubGroupDescription\": true, \"ShowSubgroupToggle\": false, \"GroupDescription\": \"Diese Cookies werden von einer Reihe von Social Media-Diensten gesetzt, die wir auf der Website verwenden, damit Sie unsere Inhalte mit Ihren Freunden und Netzwerken teilen können. Diese Cookies sind in der Lage, Ihren Browser über andere Websites hinweg zu verfolgen und ein Profil Ihrer Interessen zu erstellen. Dies kann sich auf Inhalte und Nachrichten auswirken, die Sie auf anderen Websites sehen. Wenn Sie diese Cookies nicht zulassen, können Sie diese Freigabetools möglicherweise nicht verwenden oder sehen.\", \"GroupName\": \"Social\", \"IsIabPurpose\": false, \"FirstPartyCookies\": [], \"Hosts\": [{\"HostName\": \".vimeo.com\", \"HostId\": \"nhz\", \"Description\": \"\", \"Cookies\": [{\"Name\": \"vuid\", \"Host\": \".vimeo.com\", \"IsSession\": false, \"Length\": \"365\", \"description\": \"\"}]}], \"PurposeId\": \"\", \"CustomGroupId\": \"C0005\", \"GroupId\": \"4b084412-21b9-48fe-add5-3706c090bfa9\", \"Status\": \"inactive\", \"IsDntEnabled\": false}, {\"ShowInPopup\": true, \"Order\": \"5\", \"OptanonGroupId\": \"C0004\", \"Parent\": \"\", \"ShowSubgroup\": true, \"ShowSubGroupDescription\": true, \"ShowSubgroupToggle\": false, \"GroupDescription\": \"Diese Cookies können über unsere Website von unseren Werbepartnern gesetzt werden. Sie können von diesen Unternehmen verwendet werden, um ein Profil Ihrer Interessen zu erstellen und Ihnen relevante Anzeigen auf anderen Websites zu zeigen. Sie speichern nicht direkt personenbezogene Daten, basieren jedoch auf einer einzigartigen Identifizierung Ihres Browsers und Internet-Geräts. Wenn Sie diese Cookies nicht zulassen, werden Sie weniger gezielte Werbung erleben.\", \"GroupName\": \"Marketing\", \"IsIabPurpose\": false, \"FirstPartyCookies\": [{\"Name\": \"_gcl_au\", \"Host\": \"example.com\", \"IsSession\": false, \"Length\": \"90\", \"description\": \"Used by Google AdSense for experimenting with advertisement efficiency across websites using their services\"}, {\"Name\": \"_fbp\", \"Host\": \"com\", \"IsSession\": false, \"Length\": \"90\", \"description\": \"Used by Facebook to deliver a series of advertisement products such as real time bidding from third party advertisers\"}], \"Hosts\": [{\"HostName\": \".facebook.com\", \"HostId\": \"wvu\", \"Description\": \"\", \"Cookies\": [{\"Name\": \"fr\", \"Host\": \".facebook.com\", \"IsSession\": false, \"Length\": \"90\", \"description\": \"Contains browser and user unique ID combinaton, used for targeted advertising.\"}]}, {\"HostName\": \"facebook.com\", \"HostId\": \"pwp\", \"Description\": \"\", \"Cookies\": [{\"Name\": \"fr\", \"Host\": \"facebook.com\", \"IsSession\": false, \"Length\": \"2914642\", \"description\": \"Contains browser and user unique ID combinaton, used for targeted advertising.\"}]}, {\"HostName\": \"www.facebook.com\", \"HostId\": \"aqv\", \"Description\": \"\", \"Cookies\": [{\"Name\": \"\", \"Host\": \"www.facebook.com\", \"IsSession\": true, \"Length\": \"0\", \"description\": \"This domain is owned by Facebook, which is the world's largest social networking service.  As a third party host provider, it mostly collects data on the interests of users via widgets such as the 'Like' button found on many websites.  This is used to serve targeted advertising to its users when logged into its services.  In 2014 it also started serving up behaviourally targeted advertising on other websites, similar to most dedicated online marketing companies.\"}]}], \"PurposeId\": \"D96A94B5-1095-470B-B45D-CA403E37244C\", \"CustomGroupId\": \"C0004\", \"GroupId\": \"4bc15ca1-6ef9-4694-9bdc-2fb95ecedae7\", \"Status\": \"inactive\", \"IsDntEnabled\": false}]"

以前有人见过这种行为吗?是什么原因造成的?这是 Onstrust 中的错误还是由我们的网站引起的?

我检查了stringify是否被覆盖了,但我好像没有:

JSON.stringify
ƒ stringify() { [native code] }

编辑:实际上它似乎是一个数组?我尝试对每个项目进行字符串解析,这些都有效。但不是完整的:

EDIT2:我还没有一个最小可重现的例子,但我做了另一个重要的观察:

JSON.stringify 当在数组上使用 stringify 时,我的页面通常似乎被破坏了。

typeof JSON.parse(JSON.stringify(["foo"]));
"string"

JSON.stringify(["foo"])
"\"[\\"foo\\"]\""

在其他页面上它有效。

所以我的问题更像是:JSON stringify 如何在那个页面被覆盖而 JSON.stringify.toSource() 仍然只显示 "native code".

问题似乎是,我定义了一个 Array.prototype.toJSON:

delete Array.prototype.toJSON

typeof JSON.parse(JSON.stringify(["foo"]));
"object"

在此处找到:JSON.stringify() array bizarreness with Prototype.js

页面加载 prototype.js 定义了 toJSON。