java - Axios 请求 - 来自 PHP API 的 Gzip 数据
问题描述
是否可以在 PHP 中 gzcompress 数据然后让 Axios 请求它?
我试过这样做,但不断收到此错误:“格式错误的 UTF-8 字符,可能编码不正确。”
我的 Axios 请求如下所示:
axios({
method: 'get',
url: 'https://someapi.com/api/test',
data: { },
config: { headers: { 'Content-Type': 'application/json', 'Accept-Encoding': 'gzip' }}
})
.then(response => {
response.data.forEach(el => {
this.transactions.push(JSON.parse(el));
this.transactionsFull = this.transactions;
});
this.loading = false;
console.log(this.transactions);
})
.catch(e => {
this.errors.push(e)
})
$result = openssl_decrypt($cipher_text, 'aes-256-gcm', $key, OPENSSL_RAW_DATA, $iv, $auth_tag);
$json = json_decode($result);
$channel = Channel::where('uuid', $json->payload->authentication->entityId)->first();
$gzencode = gzencode(json_encode(array('transaction' => $json, 'relation' => json_decode($channel))), 8);
Redis::lpush('transactions_gzencode', $gzencode);
$length = 0;
$transactions = Redis::lrange('transactions_gzencode', 0, -1);
foreach($transactions as $item) {
$length += strlen($item);
}
header('Content-Encoding: gzip');
header('Content-Type: application/json');
header('Content-Length: ' . $length);
return $transactions;
解决方案
我相信 axios 是无法解压 gzip 的,但是浏览器应该可以在 axios 甚至没有接触到响应之前做到。但要让浏览器这样做,您必须使用正确的 http 标头和格式进行响应。
请注意,根据 php 文档,要在 http 响应正文中使用压缩数据,您必须使用 gzencode,而不是 gzcompress。
示例 PHP:
$compressed = gzencode(json_encode(['test' => 123]));
header('Content-Type: application/json');
header('Content-Encoding: gzip');
header('Content-Length: ' . strlen($compressed));
echo $compressed;
示例 JS:
console.log(await (await fetch('/test')).json());
// {test: 123}
编辑
由于您要做的是发送一组单独压缩的项目,因此您可以在 JSON 编码的 base64 编码二进制压缩数据数组中输出数据。
如何使用 pako.js 解压从服务器返回的压缩事务数组的示例:
PHP:
$transactions = ['first', 'second', 'third'];
echo json_encode(array_map('base64_encode', array_map('gzencode', $transactions)));
JS:
(async () => {
const transactions = (await (await fetch('/test')).json())
.map(atob)
.map(blob => pako.inflate(blob, { to: 'string' }));
console.log(transactions);
})();
请注意,现在我没有包含标题,因为我只是发送一个常规的 json 编码数组。
这种方法的缺点是压缩数据不会有太多好处,因为它在发送到客户端之前会转换为 base64。必须编码为 base64,否则 json_encode 会尝试将二进制数据作为字符串处理,这会导致字符串编码错误。
您仍然可以在发送到客户端之前压缩生成的 json 编码字符串,就像我之前的答案一样,但我不确定压缩是否仍然足够好:
$compressedTransactions = array_map('gzencode', ['first', 'second', 'third']);
$compressed = gzencode(json_encode(array_map('base64_encode', $compressedTransactions)));
header('Content-Type: application/json');
header('Content-Encoding: gzip');
header('Content-Length: ' . strlen($compressed));
echo $compressed;
推荐阅读
- pycharm - PyCharm 键盘快捷键和突出显示问题
- c# - C#动态控制anchor失形
- plugins - 构建 NativeScript 插件时如何访问硬件层?
- python - Pandas - Dataframe 有包含列表的列。如何按列表中的元素分组?
- c# - 如何测试将身份与只读属性一起使用的控制器?
- google-chrome-devtools - 控制台中的问题:Uncaught SyntaxError: Invalid or unexpected token
- c# - MVC 中的 Kindo Grid 显示原始数据
- mongodb - 基于一个值合并mongodb聚合中的两个集合
- android - Picasso 无法解析方法“With(android.content.Context)”
- rest - 使用 (ADO rest api) 在 Azure Repos 中列出特定提交的标签