Stackoverflow是广大程序猿赖以生存的工具之一,在stackoverflow搜索技术问题得到答案的质量和正确率远远高于其他平台。但是这么一个好网站居然因为Google被墙而无法正常使用(无法登录,无法评论、回答问题等)着实让人不爽呀。以前还有V**可以用的,现在大部分V**都被查封了。。程序员的日子真的是越来越难过了呀。。所以我下决心想办法自己解决这个令人头疼问题。
首先我们找到Stackoverflow无法正常使用的原因。我们打开stackoverflow的网站,发现网页最上面有一行醒目的提示:
Stack Overflow requires external JavaScript from another domain, which is blocked or failed to load.
翻译一下就是:
Stack Overflow需要使用其他域名下面的某些JS文件,但它们被阻止访问或者加载失败了。
由此我们应该想到应该是某些JS文件加载的问题了。
打开浏览器控制台,发现控制台报了很多的错,如下图:
我们发现第一个错是获取https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js 失败了,因为Google被墙了,导致其域名下的js文件也访问不了,而这个jquery获取失败导致了后面一连串的js报错。所以我们解决问题的关键变成了能让stackoverflow加载这个jquery文件。除了访问外国网站或者Google被解封,不然我们不可能从原有地址获取该jquery文件,但是我不想用V**(因为买不起),所以我想能不能从其他CDN获取相同版本的jquery文件再让stackoverflow加载呢?这是完全可以的,只要我们在stackoverflow网页加载的过程中将google jquery的script标签替换成其他CDN的应该就可以了。但是怎么实现访问所有stackoverflow域名下的页面都能实现自动替换呢?
我之前接触过一个Chrome的插件叫 TamperMonkey,这个工具允许用户自己创建js脚本并挂载到目标网页上,以实现修改网页样式、行为的目的。所以TamperMonkey应该可以实现我们替换script标签的目的。
TamperMonkey为主流浏览器(Chrome, Microsoft Edge, Safari, Opera Next, 和 Firefox)都提供了插件,大家可以选择自己习惯的浏览器安装。
我们先给浏览器安装TamperMonkey插件,我用的Chrome,但是由于Google被墙(可恶的*),我们不能通过Google Web Store安装,所以只能从第三方下载并手动安装。
TamperMonkey下载地址: 微云下载
下载完成后,打开Chrome的Extensions页面:
将刚刚下载的.crx插件文件拖到Extensions窗口,点击Add Extension:
这样TamperMonkey就安装完成了。
接下来就是写脚本替换原有的google jquery引用了。
我们先来看下google的jquery引用在页面中的样子:
可以看到就是普通的script标签,现在我们的思路应该比较明确了,就是用javascript进行DOM操作将原有的script标签替换。
首先我们打开TamperMonkey,新建一个脚本。脚本内容如下:
// ==UserScript==
// @name GoogleJsReplace
// @namespace https://stackoverflow.com/
// @version 0.1
// @description try to take over the world!
// @author You
// @match https://stackoverflow.com/
// @grant none
// ==/UserScript==
(function() {
'use strict';
function createScriptElement(file) {
var jsElm = document.createElement("script");
jsElm.src = file;
return jsElm;
}
function replaceGoogleScripts(){
var scripts = document.querySelectorAll('script');
scripts.forEach(function (script) {
var matches = script.src.match(/jquery\/([\d\.]+)\/jquery.min.js/);
if (matches) {
var version = matches[1];
var newSrc = 'https://cdn.bootcss.com/jquery/' + version + '/jquery.min.js';
script.parentNode.replaceChild(createScriptElement(newSrc), script);
console.log('replaced google jquery with ' + newSrc);
}
});
}
replaceGoogleScripts();
})();
脚本的内容很简单,找到页面内jquery的script标签,将其替换成一个新的script标签,src为bootcss cdn的jquery地址(试验了jquery官方和微软的cdn,访问速度都不如bootcss快)。
新增脚本后,我们还需要对脚本的使用场景做一些设置。首先我们需要设置脚本运行的时间点,我们希望在google的jquery script刚被添加到DOM中时就替换它,但是在查阅了大量的资料后我发现这个做不到(如果有人知道怎么做,欢迎留言),所以我们只能选择在尽量早的时间点去执行脚本,让jquery尽量早加载完。TamperMonkey提供了几个执行的点,通过配置 run-at实现。我们选择最早的时间点document-start,配置如图:
我们还想该脚本只对stackoverflow网站有效,我们可以使用 @include 或者 @match实现。我选择用match,配置如图:
到此为止,大功告成。我们打开 stackoverflow.com,可以看到jquery已经成功下载,网页头部的红色提示信息也消失了,网站可以正常使用了。