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

Posted

技术标签:

【中文标题】JSON.parse(JSON.stringify(e)) 将对象转换为字符串【英文标题】:JSON.parse(JSON.stringify(e)) converts object to a string 【发布时间】:2020-04-16 16:03:49 【问题描述】:

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

我将问题归结为 onetrust 使用 JSON.parse(JSON.stringify(e)) 来克隆对象。我读过这是一种不好的做法,但我无法更改该代码。

归结为 - 所以在 stringify 和 parse 之后类型发生了变化。

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:我还没有 Minimal Reproducible 示例,但我做了另一个重要的观察:

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

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

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

在其他页面上也可以。

所以我的问题更像是:JSON stringify 如何在该页面被覆盖,而 JSON.stringify.toSource() 仍然只显示“本机代码”。

【问题讨论】:

minimal reproducible example 真的很有帮助。您提供的 JSON 字符串似乎解析得很好。 不是真正的 MRE,但编辑了我的问题 (EDIT2) 无法重现 JSON API 不当行为。可能是本机实现被其他一些“框架”(hack/work-around)重载了吗? 这是prototypeJs。看我的回答 【参考方案1】:

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

delete Array.prototype.toJSON

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

在这里找到:JSON.stringify() array bizarreness with Prototype.js

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

【讨论】:

以上是关于JSON.parse(JSON.stringify(e)) 将对象转换为字符串的主要内容,如果未能解决你的问题,请参考以下文章

关于JSON.stringify()与JSON.parse()

JSON.stringify()和JSON.parse()

JSON.stringify()和JSON.parse()

JSON.stringify()与JSON.parse()区别

JSON.parse()和JSON.stringify()

JSON.parse()与JSON.stringify()与qs.stringify的区别