为什么Google在JSON中插入while(1);以及如何避免上当

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么Google在JSON中插入while(1);以及如何避免上当:JavaScript开发者的顶级错误



如果你曾经在使用Google API时查看过开发者控制台,或者只是搜索过服务器返回的奇怪响应,那么你肯定注意到过类似这样的内容:



while(1);["some","data"]


看起来像一个会挂起浏览器的无限循环,对吧?但实际上,这是一个天才的防护机制。让我们来弄清楚为什么Google在JSON前添加while(1),开发者在处理此类响应时犯了哪些错误,以及如何避免它们。



这个问题是Stack Overflow上最热门的问题之一(有数千次浏览),这并非没有原因。它不仅涉及技术细节,还涉及网络安全的基本原则。



JSON中的while(1);是什么?它从何而来?



让我们从最重要的开始。Google在JSON前添加while(1)不是为了破坏你的代码,而是为了防御一种称为JSON劫持的攻击。



想象一下过去的好时光,当时网站使用顶层JSON数组(例如[{"user":"admin","token":"secret"}])。攻击者可以覆盖全局的Array或Object构造函数,并通过<script>标签窃取数据。浏览器将JSON作为JavaScript执行,数据就泄露了。



Google的解决方案是添加前缀while(1);。这使得JSON成为无效的JavaScript(无限循环会阻止恶意脚本执行),但JSON本身仍然是正确的——只需正确解析它,删除前缀即可。



现在,这种做法已成为许多大型API的安全标准。但如果你不了解它,你的代码可能会出错。



JavaScript开发者在处理受保护的JSON时常见的5个错误



错误#1:直接尝试解析响应



最常见的错误是开发者从服务器获取响应后,直接将其传递给JSON.parse()。结果——解析错误,因为while(1);不是有效的JSON。



fetch('https://api.google.com/some-endpoint')  .then(response => response.text())  .then(data => {    // 错误!JSON.parse会失败    const parsed = JSON.parse(data);    console.log(parsed);  })  .catch(err => console.error('解析错误:', err));


如何避免:在解析之前始终删除while(1);前缀。



fetch('https://api.google.com/some-endpoint')  .then(response => response.text())  .then(data => {    // 删除防护前缀    const cleanJson = data.replace(/^\\)?\\s*while\\s*\\(\\s*1\\s*\\)\\s*;\\s*/, '');    const parsed = JSON.parse(cleanJson);    console.log(parsed);  })  .catch(err => console.error('解析错误:', err));


错误#2:使用response.json()而不进行处理



Fetch API中的response.json()方法期望纯JSON。如果服务器返回while(1);...,那么response.json()会抛出异常。开发者通常认为这是API的bug,而不是安全特性。



// 这段代码会因"Unexpected token w"错误而失败fetch('https://api.google.com/endpoint')  .then(response => response.json()) // 错误!  .then(data => console.log(data));


如何避免:使用response.text(),然后手动删除前缀。



fetch('https://api.google.com/endpoint')  .then(response => response.text())  .then(text => {    const jsonText = text.replace(/^\\)?\\s*while\\s*\\(\\s*1\\s*\\)\\s*;\\s*/, '');    return JSON.parse(jsonText);  })  .then(data => console.log(data));


错误

博客

书籍推荐