我正在尝试使用JavaScript压缩HTML并使用Ruby解压缩它。但是有些carachters没有正确处理,我正在寻找解决这个问题的方法。
我的压缩函数首先使用this function将html转换为字节数组。然后它使用js-deflate library压缩数组。最后,使用window.btoa()对其进行base64编码。
var compress = function(htmlString) {
var compressed, originalBytes;
originalBytes = Utils.stringToByteArray(htmlString);
compressed = RawDeflate.deflate(originalBytes.join(''));
return window.btoa(compressed);
};
在Ruby的一端,我有一个Decompression
类,第一个base64解码压缩的html。然后它使用Ruby Zlib
标准库来解压缩html。此过程在this Stack Overflow question thread中进行了描述。
require "base64"
require "zlib"
class Decompression
def self.decompress(string)
decoded = Base64.decode64(string)
inflate(decoded)
end
private
def self.inflate(string)
zstream = Zlib::Inflate.new(-Zlib::MAX_WBITS)
buf = zstream.inflate(string)
zstream.finish
zstream.close
buf
end
end
我正在使用此类来扩充已发送到本地服务器的压缩html,并将其写入文件。
decompressed_content = Decompression.decompress(params["compressed_content"])
File.write('decompressed.html', decompressed_content)
然后我在浏览器中打开文件,看看它是否正确。
在大多数情况下,这很好用。我可以处理Stack Overflow主页,结果如下:
你可以看到存在一些问题。有些字符没有正确显示,最明显的是标题中我名字旁边的向下箭头
和最近的标签列表中的乘法符号
如何修复代码以便正确处理页面的这些部分?
我试图强制将膨胀的html编码为UTF-8
,但它不会改变任何内容。
def self.decompress(string)
decoded = Base64.decode64(string)
# Forcing the encoding of the output doesn't do anything.
inflate(decoded).force_encoding('UTF-8')
end
def self.decompress(string)
decoded = Base64.decode64(string)
# Either does forcing the encoding of the inflate input.
inflate(decoded.force_encoding('UTF-8'))
end
一个关键是字符串的编码在Base64解码后似乎会更改为ASCII-8BIT
:
def self.decompress(string)
p "Before decode: #{string.encoding}"
decoded = Base64.decode64(string)
p "After decode: #{decoded.encoding}"
inflated = inflate(decoded)
p "After inflate: #{inflated.encoding}"
inflated
end
# Before decode: UTF-8
# After decode: ASCII-8BIT
# After inflate: ASCII-8BIT
编辑
有人问我用来获取html的方法。我只是用jQuery把它拉出页面:
$('html')[0].outerHTML
修改以显示向充气的html添加Content-Type
元标记的效果
我在充气的html中添加了<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
。我现在得到这样的问号框(顺便说一下Chrome浏览器):
如果我检查我的膨胀html的来源并将其与实际Stack Overflow html的来源进行比较,我可以看到在我名字旁边的倒三角形中使用了不同的字符。
实际SO来源: <span class="profile-triangle">▾</span>
没有元内容类型的充气来源: <span class="profile-triangle">¾</span>
带有元内容类型的充气来源: <span class="profile-triangle">�</span>
答案 0 :(得分:2)
尝试将UTF8编码添加到您获得的HTML中。喜欢
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" charset="UTF-8" />
我建议这是因为我实际上无法在源代码中看到它(ctrl + u在同一页面上)。
编辑:原来你错过了字符集!答案 1 :(得分:2)
通常,HTML的内容类型由HTTP标头和HTML代码本身决定。 如果仅发送HTML代码,则HTTP标头信息将丢失。
查看StackOverflow发送的HTTP标头:
Cache-Control:public, max-age=60
Content-Encoding:gzip
Content-Length:33200
Content-Type:text/html; charset=utf-8
Date:Tue, 23 Oct 2012 17:35:02 GMT
Expires:Tue, 23 Oct 2012 17:36:02 GMT
Last-Modified:Tue, 23 Oct 2012 17:35:02 GMT
Vary:*
如您所见,Content-type被指定为utf-8
。如果要创建文件,则需要使用HEAD中的HTML标记手动设置内容类型,如@alexandernst所示。
答案 2 :(得分:0)
alexandernst在正确的轨道上,但我实际需要添加到HTML输出的是一个元字符集标记:
<meta charset="UTF-8">
一旦我将它放入Stack Overflow主页的HTML输出中,它看起来很完美。