繁体   English   中英

在Sql server中压缩字符串并在javascript中解压

[英]Compress string in Sql server and decompress in javascript

我想将一个长字符串从我的数据库传输到我的网页。 所以,我想尝试在我的服务器中压缩我的字符串并在客户端解压缩它的方法。

到目前为止,我的 sql server 代码中有这个:

select compress('this is just a sample string')

返回这个:

0x1F8B08000000000004002BC9C82C5600A2ACD2E212854485E2C4DC829C5485E292A2CCBC7400206D53921C000000

现在我需要在我的 javascript 中使用一个函数来恢复压缩操作:

var str = "0x1F8B08000000000004002BC9C82C5600A2ACD2E212854485E2C4DC829C5485E292A2CCBC7400206D53921C000000";
alert(decompressed(str));

这应该提醒“这只是一个示例字符串”。

首先,让我解释一下 VARBINARY(MAX) 在 SSMS 中如何存储和显示的区别。
字符串“0x1F8B0800000000000...”是由存储在数据库中的 varbinary 数据的 SSMS 创建的十六进制表示。 下面的二进制值大多是不可打印的字符。 因此,如果您尝试在 Java 代码中使用此字符串,则它无法直接工作。

我在这里创建了一个例子,如果你按下“STEP”按钮,你会看到真正的价值: HexToBin

这就是为什么你的第二个例子不起作用,你需要从数据库中读取字节数组,然后在 zlib 中使用这个字节数组。

有一个很好的例子如何在 java 中使用 deflate: Java Decompress a string compression with zlib deflate

也许你想要这样的东西: https : //jsfiddle.net/58mgsy9a/

const parseString = str => {
    const strWithoutprefix = str.slice(2);
    const array = strWithoutprefix.match(/.{1,2}/g);
    return array.map(pair => parseInt(pair, 16));
};

const decompressed = gzipArray => {
    const gunzip = new Zlib.Gunzip(gzipArray);
    const plain = gunzip.decompress();
    return String.fromCharCode(...plain);
};

var str = "0x1F8B08000000000004002BC9C82C5600A2ACD2E212854485E2C4DC829C5485E292A2CCBC7400206D53921C000000";
alert(decompressed(parseString(str)));

parseString 函数接受您的输入字符串并将其转换为数字数组,因为 zlib 需要一个数字数组作为输入。 然后解压后的函数使用 zlib 解压数组。 zlib 的解压缩函数返回一个数字数组,因此我们将其转换回字符串。

当您运行此查询时: select compress('this is just a sample string') (例如使用 MSSQL Server Management Studio)您将看到二进制压缩文本的十六进制格式的文本表示。

我用一个lorem ipsum长文本进行了测试,该文本也被转换为varcharnvarchar (您可能会注意到,在该文本中没有双字节字符,但对于本示例来说无关紧要):

这个压缩的长文本存储在 MSSQL 的varbinary(max)列中:

--------VARCHAR----------    --------NVARCHAR--------
Original     Hex   Binary    Original    Hex   Binary
   13046    4024     2011       13046   4748     2373

所以,这里最好的选择是从后端传输二进制数据,而不是十六进制表示。

告诉浏览器响应已被压缩:

服务器端:这是 PHP 中的一个示例端点:

<?php  /* getcompressed.php */
    header("Content-Encoding: gzip");
    header("Vary: Accept-Encoding");
    header("Content-type: text/html; charset=UTF-16"); /* nvarchar */
    $serverName = 'testserver';
    $connectionOptions = array('Database'=>'testdatabase');
    $conn = sqlsrv_connect($serverName, $connectionOptions);  
    $sql = 'SELECT compressed FROM tb_compression WHERE id = 1';
    $qry = sqlsrv_query($conn, $sql);
    $row = sqlsrv_fetch_array($qry);
    $compressed = $row[0];
    sqlsrv_close($conn);
    echo $compressed;
?>

客户端:这是 JavaScript 中的一个工作片段:

var request = new XMLHttpRequest();
request.onload = function(e) {
    var text = e.currentTarget.responseText;
    console.log(text); /* Here You go */
};
request.responseType = 'text';
request.open('GET', 'getcompressed.php', true);
request.send(null);

这在 Chrome 和 FF 中也适用于我。 试试看。

使用 gunzip javaScript 库:

服务器端:这是 PHP 中的一个示例端点:

<?php  /* getcompressed.php */
    header('Content-Type: application/octet-stream');
    $serverName = 'testserver';
    $connectionOptions = array('Database'=>'testdatabase');
    $conn = sqlsrv_connect($serverName, $connectionOptions);  
    $sql = 'SELECT compressed FROM tb_compression WHERE id = 1';
    $qry = sqlsrv_query($conn, $sql);
    $row = sqlsrv_fetch_array($qry);
    $compressed = $row[0];
    sqlsrv_close($conn);
    echo $compressed;
?>

客户端:这是 JavaScript 中的一个工作片段:

出处:这里使用的减压图书馆是gunzip.min.jsImaya裕太

var request = new XMLHttpRequest();
request.onload = function(e) {
    var response = new Uint8Array(e.currentTarget.response);
    console.log(response.byteLength);
    /* Strip out the response termination */
    var compressed = response.subarray(0, response.byteLength - 4);
    var gunzip = new Zlib.Gunzip(compressed);
    var decompressed = gunzip.decompress();
    var encoding = 'utf-8'; /* For varchar text (ansi) */
    //var encoding = 'utf-16'; /* For nvarchar text (double-byte) */
    var text = new TextDecoder(encoding).decode(decompressed);
    console.log(text); /* Here You go */
};
request.responseType = 'arraybuffer';
request.open('GET', 'getcompressed.php', true);
request.send(null);

如果您查看response.byteLength ,对于 13046 字节的示例文本,您将检查是否只有 2015 字节有效地通过网络传输。

正如@Karl-Johan Sjögren 所说,sql 函数compress()返回一个 GZIP 值,如果不使用zlib等外部库,您将无法在 javascript 上解压缩它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM