一般的使用流程(4步):

服务器端将字符串Gzip压缩为 字节数组——>通过base64转为字符串(后传递到客户端)——>解码base64字符串为字节数组——>Gzip解码字节数组为可用字符串。

第一步:服务器端压缩(本人使用的是C#)

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Json;
using System.Text;
using System.Web;
using ICSharpCode.SharpZipLib.BZip2;
using ICSharpCode.SharpZipLib.GZip;
using ICSharpCode.SharpZipLib.Zip; namespace amtioth5.Helper
{
public enum CompressionType
{
/// <summary>
/// GZip 压缩格式
/// </summary>
GZip,
/// <summary>
/// BZip2 压缩格式
/// </summary>
BZip2,
/// <summary>
/// Zip 压缩格式
/// </summary>
Zip
} public class CompressHelper
{
public static CompressionType CompressionProvider = CompressionType.GZip; #region Public methods /// <summary>
/// 从原始字节数组生成已压缩的字节数组。
/// </summary>
/// <param name="bytesToCompress">原始字节数组。</param>
/// <returns>返回已压缩的字节数组</returns>
public static byte[] Compress(byte[] bytesToCompress)
{
MemoryStream ms = new MemoryStream();
Stream s = OutputStream(ms);
s.Write(bytesToCompress, , bytesToCompress.Length);
s.Close();
return ms.ToArray();
} /// <summary>
/// 从原始字符串生成已压缩的字符串。
/// </summary>
/// <param name="stringToCompress">原始字符串。</param>
/// <returns>返回已压缩的字符串。</returns>
public static string Compress(string stringToCompress)
{
byte[] compressedData = CompressToByte(stringToCompress);
string strOut = Convert.ToBase64String(compressedData);
return strOut;
} /// <summary>
/// 从原始字符串生成已压缩的字节数组。
/// </summary>
/// <param name="stringToCompress">原始字符串。</param>
/// <returns>返回已压缩的字节数组。</returns>
public static byte[] CompressToByte(string stringToCompress)
{
byte[] bytData = Encoding.UTF8.GetBytes(stringToCompress);
return Compress(bytData);
} /// <summary>
/// 从已压缩的字符串生成原始字符串。
/// </summary>
/// <param name="stringToDecompress">已压缩的字符串。</param>
/// <returns>返回原始字符串。</returns>
public static string DeCompress(string stringToDecompress)
{
string outString = string.Empty;
if (stringToDecompress == null)
{
throw new ArgumentNullException("stringToDecompress", "You tried to use an empty string");
} try
{
byte[] inArr = Convert.FromBase64String(stringToDecompress.Trim());
byte[] deArr = DeCompress(inArr);
outString = Encoding.UTF8.GetString(deArr, , deArr.Length);
}
catch (NullReferenceException nEx)
{
return nEx.Message;
} return outString;
} /// <summary>
/// 从已压缩的字节数组生成原始字节数组。
/// </summary>
/// <param name="bytesToDecompress">已压缩的字节数组。</param>
/// <returns>返回原始字节数组。</returns>
public static byte[] DeCompress(byte[] bytesToDecompress)
{
byte[] writeData = new byte[];
Stream s2 = InputStream(new MemoryStream(bytesToDecompress));
MemoryStream outStream = new MemoryStream(); while (true)
{
int size = s2.Read(writeData, , writeData.Length);
if (size > )
{
outStream.Write(writeData, , size);
}
else
{
break;
}
}
s2.Close();
byte[] outArr = outStream.ToArray();
outStream.Close();
return outArr;
} #endregion #region Private methods /// <summary>
/// 从给定的流生成压缩输出流。
/// </summary>
/// <param name="inputStream">原始流。</param>
/// <returns>返回压缩输出流。</returns>
private static Stream OutputStream(Stream inputStream)
{
switch (CompressionProvider)
{
case CompressionType.BZip2:
return new BZip2OutputStream(inputStream); case CompressionType.GZip:
return new GZipOutputStream(inputStream); case CompressionType.Zip:
return new ZipOutputStream(inputStream); default:
return new GZipOutputStream(inputStream);
}
} /// <summary>
/// 从给定的流生成压缩输入流。
/// </summary>
/// <param name="inputStream">原始流。</param>
/// <returns>返回压缩输入流。</returns>
private static Stream InputStream(Stream inputStream)
{
switch (CompressionProvider)
{
case CompressionType.BZip2:
return new BZip2InputStream(inputStream); case CompressionType.GZip:
return new GZipInputStream(inputStream); case CompressionType.Zip:
return new ZipInputStream(inputStream); default:
return new GZipInputStream(inputStream);
}
} #endregion public static T FromJsonTo<T>(string jsonString)
{ DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); T jsonObject = (T)ser.ReadObject(ms); ms.Close(); return jsonObject;
} public static string ToJsonString(object item)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(item.GetType()); using (MemoryStream ms = new MemoryStream())
{
serializer.WriteObject(ms, item); StringBuilder sb = new StringBuilder(); byte[] bytes = ms.ToArray(); sb.Append(Encoding.UTF8.GetString(bytes, , bytes.Length)); return sb.ToString();
}
}
}
}

http://icsharpcode.github.io/SharpZipLib/  (需要一个依赖库是开源的)

第二步:使用base64将压缩后的字节变为base64字符串 (Convert.ToBase64String();)

此转换为.net平台里面自带的函数。

第三部:客户端在Javascript中利用zip.js将base64字符串解码为压缩字节

var bytes = Base64.decodeToBytes(base_ut8);///important

上面代码将base_ut8变量中的字符串转为字节数组。

第四部:解压第三步得到的字节数组

// compressed = Array.<number> or Uint8Array
var gunzip = new Zlib.Gunzip(compressed);
var plain = gunzip.decompress();

下面我写的一个流程

document.write("<script src='../Gzip/base64.js'></script>");
document.write("<script src='../Gzip/zlib_and_gzip.min.js'></script>");
document.write("<script src='../Gzip/encoding-indexes.js'></script>");
document.write("<script src='../Gzip/encoding.js'></script>");
var GzipHelper={
DeCompressGzip:function(base64str){
if(base64str===null||base64str==='') return '';
var bytes = Base64.decodeToBytes(base64str);
var gunzip = new Zlib.Gunzip ( bytes );
var plain = gunzip.decompress();
var asciistring = new TextDecoder("utf-8").decode(plain);
return asciistring; },
CompressGzip:function(jsonstr){
}
}

相关文件下载链接: http://pan.baidu.com/s/1jING8Hw 密码: erap

base64的转码和解码

/**
* UTF16和UTF8转换对照表
* U+00000000 – U+0000007F 0xxxxxxx
* U+00000080 – U+000007FF 110xxxxx 10xxxxxx
* U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
* U+00010000 – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* U+00200000 – U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
* U+04000000 – U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
var Base64 = {
// 转码表
table : [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O' ,'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
'='
],
UTF16ToUTF8 : function(str) {
var res = [], len = str.length;
for (var i = 0; i < len; i++) {
var code = str.charCodeAt(i);
if (code > 0x0000 && code <= 0x007F) {
// 单字节,这里并不考虑0x0000,因为它是空字节
// U+00000000 – U+0000007F 0xxxxxxx
res.push(str.charAt(i));
} else if (code >= 0x0080 && code <= 0x07FF) {
// 双字节
// U+00000080 – U+000007FF 110xxxxx 10xxxxxx
// 110xxxxx
var byte1 = 0xC0 | ((code >> 6) & 0x1F);
// 10xxxxxx
var byte2 = 0x80 | (code & 0x3F);
res.push(
String.fromCharCode(byte1),
String.fromCharCode(byte2)
);
} else if (code >= 0x0800 && code <= 0xFFFF) {
// 三字节
// U+00000800 – U+0000FFFF 1110xxxx 10xxxxxx 10xxxxxx
// 1110xxxx
var byte1 = 0xE0 | ((code >> 12) & 0x0F);
// 10xxxxxx
var byte2 = 0x80 | ((code >> 6) & 0x3F);
// 10xxxxxx
var byte3 = 0x80 | (code & 0x3F);
res.push(
String.fromCharCode(byte1),
String.fromCharCode(byte2),
String.fromCharCode(byte3)
);
} else if (code >= 0x00010000 && code <= 0x001FFFFF) {
// 四字节
// U+00010000 – U+001FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
} else if (code >= 0x00200000 && code <= 0x03FFFFFF) {
// 五字节
// U+00200000 – U+03FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
} else /** if (code >= 0x04000000 && code <= 0x7FFFFFFF)*/ {
// 六字节
// U+04000000 – U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
}
} return res.join('');
},
UTF8ToUTF16 : function(str) {
var res = [], len = str.length;
var i = 0;
for (var i = 0; i < len; i++) {
var code = str.charCodeAt(i);
// 对第一个字节进行判断
if (((code >> 7) & 0xFF) == 0x0) {
// 单字节
// 0xxxxxxx
res.push(str.charAt(i));
} else if (((code >> 5) & 0xFF) == 0x6) {
// 双字节
// 110xxxxx 10xxxxxx
var code2 = str.charCodeAt(++i);
var byte1 = (code & 0x1F) << 6;
var byte2 = code2 & 0x3F;
var utf16 = byte1 | byte2;
res.push(Sting.fromCharCode(utf16));
} else if (((code >> 4) & 0xFF) == 0xE) {
// 三字节
// 1110xxxx 10xxxxxx 10xxxxxx
var code2 = str.charCodeAt(++i);
var code3 = str.charCodeAt(++i);
var byte1 = (code << 4) | ((code2 >> 2) & 0x0F);
var byte2 = ((code2 & 0x03) << 6) | (code3 & 0x3F);
var utf16 = ((byte1 & 0x00FF) << 8) | byte2
res.push(String.fromCharCode(utf16));
} else if (((code >> 3) & 0xFF) == 0x1E) {
// 四字节
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
} else if (((code >> 2) & 0xFF) == 0x3E) {
// 五字节
// 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
} else /** if (((code >> 1) & 0xFF) == 0x7E)*/ {
// 六字节
// 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
}
} return res.join('');
},
encode : function(str) {
if (!str) {
return '';
}
var utf8 = this.UTF16ToUTF8(str); // 转成UTF8
var i = 0; // 遍历索引
var len = utf8.length;
var res = [];
while (i < len) {
var c1 = utf8.charCodeAt(i++) & 0xFF;
res.push(this.table[c1 >> 2]);
// 需要补2个=
if (i == len) {
res.push(this.table[(c1 & 0x3) << 4]);
res.push('==');
break;
}
var c2 = utf8.charCodeAt(i++);
// 需要补1个=
if (i == len) {
res.push(this.table[((c1 & 0x3) << 4) | ((c2 >> 4) & 0x0F)]);
res.push(this.table[(c2 & 0x0F) << 2]);
res.push('=');
break;
}
var c3 = utf8.charCodeAt(i++);
res.push(this.table[((c1 & 0x3) << 4) | ((c2 >> 4) & 0x0F)]);
res.push(this.table[((c2 & 0x0F) << 2) | ((c3 & 0xC0) >> 6)]);
res.push(this.table[c3 & 0x3F]);
} return res.join('');
},
decode : function(str) {
if (!str) {
return '';
} var len = str.length;
var i = 0;
var res = []; while (i < len) {
code1 = this.table.indexOf(str.charAt(i++));
code2 = this.table.indexOf(str.charAt(i++));
code3 = this.table.indexOf(str.charAt(i++));
code4 = this.table.indexOf(str.charAt(i++)); c1 = (code1 << 2) | (code2 >> 4);
c2 = ((code2 & 0xF) << 4) | (code3 >> 2);
c3 = ((code3 & 0x3) << 6) | code4; res.push(String.fromCharCode(c1)); if (code3 != 64) {
res.push(String.fromCharCode(c2));
}
if (code4 != 64) {
res.push(String.fromCharCode(c3));
} } return this.UTF8ToUTF16(res.join(''));
},
decodeToBytes : function(str) {
if (!str) {
return '';
} var len = str.length;
var i = 0;
var res = []; while (i < len) {
code1 = this.table.indexOf(str.charAt(i++));
code2 = this.table.indexOf(str.charAt(i++));
code3 = this.table.indexOf(str.charAt(i++));
code4 = this.table.indexOf(str.charAt(i++)); c1 = (code1 << 2) | (code2 >> 4);
c2 = ((code2 & 0xF) << 4) | (code3 >> 2);
c3 = ((code3 & 0x3) << 6) | code4;
res.push(c1);
if (code2 != 64) {
res.push(c2);
}
if (code3 != 64) {
res.push(c3);
} }
res.pop(); return res;
}
};

Gzip的转码和解码(zlib.js库)

https://github.com/imaya/zlib.js/blob/master/README.en.md

附带一个编码转换库(text-encoding)

https://github.com/inexorabletash/text-encoding

javascript中base64和Gzip的使用的更多相关文章

  1. Javascript中Base64编码解码的使用实例

    Javascript为我们提供了一个简单的方法来实现字符串的Base64编码和解码,分别是window.btoa()函数和window.atob()函数. 1 var encodedStr = win ...

  2. javascript中的Base64.UTF8编码与解码详解

    javascript中的Base64.UTF8编码与解码详解 本文给大家介绍的是javascript中的Base64.UTF8编码与解码的函数源码分享以及使用范例,十分实用,推荐给小伙伴们,希望大家能 ...

  3. 前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型

    前端开发:面向对象与javascript中的面向对象实现(二)构造函数与原型 前言(题外话): 有人说拖延症是一个绝症,哎呀治不好了.先不说这是一个每个人都多多少少会有的,也不管它究竟对生活有多么大的 ...

  4. nodejs与javascript中的aes加密

    简介 1.aes加密简单来说,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准.这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用.高级加密标准已然成为对称密钥加 ...

  5. JavaScript中typeof、toString、instanceof、constructor与in

    JavaScript 是一种弱类型或者说动态语言.这意味着你不用提前声明变量的类型,在程序运行过程中,类型会被自动确定. 这也意味着你可以使用同一个变量保存不同类型的数据. 最新的 ECMAScrip ...

  6. JavaScript 进阶教程一 JavaScript 中的事件流 - 事件冒泡和事件捕获

    先看下面的示例代码: <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Jav ...

  7. 用javascript实现base64编码器

    前面的话 base-64作为常见的编码函数,在基本认证.摘要认证以及一些HTTP扩展中得到了大量应用.在前端领域,也常常把图片转换为base-64编码在网络中传输.本文将详细介绍base64的原理及用 ...

  8. JavaScript中apply与call方法

    一.定义 apply:应用某一对象的一个方法,用另一个对象替换当前对象. call:调用一个对象的一个方法,以另一个对象替换当前对象. 二.apply //apply function Person( ...

  9. 【JavaScript中typeof、toString、instanceof、constructor与in】

    JavaScript中typeof.toString.instanceof.constructor与in JavaScript 是一种弱类型或者说动态语言.这意味着你不用提前声明变量的类型,在程序运行 ...

随机推荐

  1. Wordpress更换主题之后出错

    今天吃完午饭,休息休息,最近搞了一下google adsense,不过最终的审核没通过,我想会不会是界面不好看呢,饭后就在电脑旁,更换了几个wordpress主题,我的博客使用wordpress搭建的 ...

  2. 菜单之一:Menu基础内容

    参考<疯狂android讲义>2.10节P168 1.重要接口 Android菜单相关的重要接口共有以下四个: 其中Menu为普通菜单,SubMenu包含子项,ContextMenu当长时 ...

  3. 最大连续子序列(HDU 1231 DP)

    最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  4. 动态PDF在线预览

    实战动态PDF在线预览及带签名的PDF文件转换 开篇语: 最近工作需要做一个借款合同,公司以前的合同都是通过app端下载,然后通过本地打开pdf文件,而喜欢创新的我,心想着为什么不能在线H5预览,正是 ...

  5. C语言经典程序190例

    [程序1] 题目:809*??=800*??+9*??+1 其中??代表的两位数,8*??的结果为两位数,9*??的结果为3位数.求??代表的两位数,及809*??后的结果. 1.程序分析: 2.程序 ...

  6. Qt5中生成和使用静态库

    在QT中静态库的后缀名为.a,在vs中开发的静态库后缀名为.lib.QT版本为5.2.1,系统为Windows. 一. 静态库的生成 新建项目. 新建一个静态库的项目,如图1.1所示:项目名称为tes ...

  7. LLinux系统编程(10)——进程间通信之管道

    管道是Linux中很重要的一种通信方式,是把一个程序的输出直接连接到另一个程序的输入,常说的管道多是指无名管道,无名管道只能用于具有亲缘关系的进程之间,这是它与有名管道的最大区别.有名管道叫named ...

  8. C语言的本质(32)——C语言与汇编之C语言内联汇编

    用C写程序比直接用汇编写程序更简洁,可读性更好,但效率可能不如汇编程序,因为C程序毕竟要经由编译器生成汇编代码,尽管现代编译器的优化已经做得很好了,但还是不如手写的汇编代码.另外,有些平台相关的指令必 ...

  9. sqlexpress 不用管理工具 sa

    操作步骤: 开始=>运行=>(快捷键:win+R) cmd, 屎劲敲回车. 出现黑色的DOS窗体后,输入如下几条命令: 1.SQLCMD -S (local)\sqlexpress -E ...

  10. GNU C - 关于8086的内存访问机制以及内存对齐(memory alignment)

    一.为什么需要内存对齐? 无论做什么事情,我都习惯性的问自己:为什么我要去做这件事情? 是啊,这可能也是个大家都会去想的问题, 因为我们都不能稀里糊涂的或者.那为什么需要内存对齐呢?这要从cpu的内存 ...