前段时间和 Kiosr 聊天的时候,他说玩了一个很鬼畜的东西。
直接看他博客源码,发现 JS 只有如下几句话:
<scrpit>Function(''.replace(/.{4}/g,function(a){return String.fromCharCode(parseInt(a.replace(/./g,function(a){'';return{'':'00','':'01','':'10','':'11'}[a]}),2))}))();</scrpit>
然后就没有任何引用 JS 文件的地方或语句了。
Kiosr 告诉我他把 JS 写在图片里了。
当时我是懵逼的,JS 写在图片里,什么骚操作?
于是抱着好奇心,找到了类似案例【原文】,实践了下:
创建图片流程:
字符串转换成 ascii 码;
创建足够存储空间的 canvas;
将字符填入到像素中(忽略 alpha 值);
获取 data url;
canvas.toDataURL( "image/png" );
存为 png 图片。
<textarea id="base64"></textarea>
<script>
function encodeUTF8(str) {
return String(str).replace(
/[\u0080-\u07ff]/g,
function(c) {
var cc = c.charCodeAt(0);
return String.fromCharCode(0xc0 | cc >> 6, 0x80 | cc & 0x3f);
}).replace(
/[\u0800-\uffff]/g,
function(c) {
var cc = c.charCodeAt(0);
return String.fromCharCode(0xe0 | cc >> 12, 0x80 | cc >> 6 & 0x3f, 0x80 | cc & 0x3f);
});
}
function request(url, loaded) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4)
if (xmlhttp.status == 200)
loaded(xmlhttp);}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
void function(){
var source = 'your.js'; //你的 JS 地址
request(source, function(xmlhttp){
var text = encodeUTF8(xmlhttp.responseText);
var pixel = Math.ceil((text.length + 2) / 3);
var size = Math.ceil(Math.sqrt(pixel));
var canvas = document.createElement('canvas');
canvas.width = canvas.height = size;
var context = canvas.getContext("2d"),
imageData = context.getImageData(0, 0, canvas.width, canvas.height),
pixels = imageData.data;
for(var i = 0, j = 0, l = pixels.length; i < l; i++){
if (i % 4 == 3) {
pixels[i] = 255;
continue;}
var code = text.charCodeAt(j++);
if (isNaN(code)) break;
pixels[i] = code;}
context.putImageData(imageData, 0, 0);
document.getElementById('base64').value = canvas.toDataURL("image/png");
});
}();
</script>
调用加载流程:
加载 png;
将 png 原尺寸绘制到 canvas 中;
读取像素中的字符串;
生成相应协议的 data url 使用。
<script>
void function(){
var source = 'your.png'; //你的图片地址
var img = document.createElement('img');
img.onload = function(){
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext("2d");
context.drawImage(img, 0, 0);
var imageData = context.getImageData(0, 0, canvas.width, canvas.height),
pixels = imageData.data;
var script = document.createElement('script');
var buffer = [];
for (var i = 0, l = pixels.length; i < l; i++) {
if (i % 4 == 3) continue;
if (!pixels[i]) break;
buffer.push(String.fromCharCode(pixels[i]));}
script.src = 'data:text/javascript;charset=utf-8,' + encodeURIComponent(buffer.join(''));
document.body.appendChild(script);
script.onload = function(){
alert(T.date.format(new Date, 'yyyy 年 M 月 d 日'));}
img = null;}
img.src = source;
}();
</script>
同时注意,需要转换的 JS 里有中文的话,需要将中文的编码转为 Unicode 编码,否者无法显示正常中文。
最终我测试了下,大概原来不到 20KB 的 JS 文件可以压缩成了一张 10KB 左右的 PNG 图片,还是蛮 666 的,哈哈。
Kiosr 告诉我,他还在想看看怎么让它变成一张正常的图片,利用起来。
或者是分段式按需加载,每篇文章都有头图,也能利用起来,这样的话,每篇文章都可以拥有独特的效果。
我只能说太骚了,哈哈。