据说 Disqus 在中国被墙了,而我的博客又是使用 Disqus 做评论系统的,这便很难为人了。一方面我并不想去掉 Disqus,一方面 Disqus 的脚本会导致文章页面一直片于加载状态,很是尴尬。
于是便想着是否可以先探测一下当前浏览者是不是处于中国局域网,如果不是的话,再加载 Disqus 组件。无论是 <img> 还是 <iframe>,都会让浏览器显示加载状态,而 XMLHttpRequest 则不会,所以使用 XMLHttpRequest 请求一个被墙的资源就可以判断了。
首先想到的便是 Disqus 的 embed.js:
var xhr = new XMLHttpRequest
xhr.open('GET', 'https://lepture.disqus.com/embed.js', true)
xhr.send()但是这个 script 不支持跨域,console 里会显示出错警告。我们依旧可以用 xhr.readState 判断出当前 emebed.js 是否下载下来了,从而知道当前浏览器是否位于中国,可是有一个出错警告还是挺讨厌的。
后来发现还可以用 Facebook 的 API 来做测试,因为 Facebook API 有加 Access-Control-Allow-Origin:*。没有跨域问题,我们使用 graph.facebook.com/feed 作为测试接口:
function isInChina(cb) {
var url = '//graph.facebook.com/feed?callback=h';
var xhr = new XMLHttpRequest();
var called = false;
xhr.open('GET', url);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
called = true;
cb(false);
}
};
xhr.send();
// timeout 1s, this facebook API is very fast.
setTimeout(function() {
if (!called) {
xhr.abort();
cb(true);
}
}, 1000);
};
注意上面加了 callback 参数,这是因为这个请求本身是有问题的,缺少 OAuth Token,如果直接请求 graph.facebook.com/feed 的话,便是 400 了。我们假装成是一个 JSONP 请求,status code 便是 200 了。
由是,我们便可知当前浏览者是否在中国局域网区,如果位于正常区域的话,便可以加载 Disqus 了。可访问我博客的中文文章页面,来看具体效果。