賞金將在 5 天后到期。此問題的答案有資格獲得 100聲望賞金。 10GeV想提請更多關注這個問題:
一個明確的解決方案將是理想的,但我也愿意接受有關如何進一步除錯和/或診斷問題的建議。如果我可以提供任何可能有用的附加資訊,請告訴我。
背景。
我的任務是除錯一些PHP和代碼,這些JavaScript代碼旨在gzip從主機服務器中提取靜態的 'ed JSON 檔案,并操縱生成的 JSON 物件的引數。
為我濫用術語提前道歉。我有一些軟體開發經驗,但很少有網路/服務器開發經驗(幾乎沒有PHP/ JavaScript)。
代碼。
要從主機服務器“拉”.json.gz檔案,使用 jQuery 的 Ajax 函式:
function myJsonReader() {
var myJsonFileUrl = getUrl();
function doFunStuffWithJsonFile(jsonObject) {
// Fun things happen
}
$.ajax({
url: myJsonFileUrl,
type: "GET",
dataType: "json",
success: doFunStuffWithJsonFile,
error: function(jqxhr, status, exception) {
console.log("Exception " exception);
alert('Failure:', exception);
}
});
}
服務器端,我們有一個index.php檔案,前幾行是:
<?php
header('Accept-Encoding: gzip');
header('Content-Encoding: gzip');
?>
<html>
<head>
... some HTML code
AjaxGET請求失敗。我知道該檔案存在,并且我正在傳遞絕對路徑。此外,如果我使用dataType: "text",我可以讀取壓縮檔案,但這當然會回傳“垃圾”:
????%^??0??jN?L/??8??@??x???351?g?? ??~???????/??7???^??di9?y;jY??6?$K?=??4??QTMB?^or??M?P????*}??G?t??K!#?8?Z@[d?9?#????R??N?????y??????????;9?T????B ??VM?#??.:?<??F?PZ???l[K?N[? G?ě?.5;P6?H??je???<?e""?h?-!?>??S?E??Q?m?H?.?SAyc?S?MsFHF?K]?H)/ry`?6.??&??-ME???s?????GA??@?rJ?.????)??kR?Vi?6??h?K-`????????
如果我使用以下命令檢查 XHR 回應:
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
我也得到垃圾。
該檔案是一個有效的 JSON 檔案,Vim 可以通過其內置gunzip功能讀取。此外,此代碼以前能夠使用 Ajax 呼叫且不使用外部庫而毫無問題地讀取這些 gzip 壓縮的 JSON 檔案,直到假定已經進行了一些未知的更改(由于混亂且大部分未記錄,這是不可能的追蹤該變化)。
不幸的是,無法簡單地解壓縮我們希望使用此功能讀取的所有檔案,也無法使用外部庫(例如zlib)。
一些訊息來源表明這應該是相對簡單的(例如這個 StackOverflow 帖子和這個)。可悲的是,我不清楚我錯過了什么。
編輯。
重新加載頁面后,我檢查了NetworkChrome 的檢查器中的選項卡。我看到了Fetch/XHR對我的 JSON 檔案的請求。其標題包括以下內容:
Requested Method: GET
Content-Type: application/x-gzip
Accept: application/json, text/javascript, */*; q=0.01
Accept-Encoding: gzip, deflate
Status Code: 200 OK
在我未經訓練的眼睛看來,它似乎已正確配置為接受壓縮檔案。
uj5u.com熱心網友回復:
如果您的服務器為 AJAX 呼叫回傳此標頭:
Content-Type: application/x-gzip
沒有這個:
Content-Encoding: gzip
那么瀏覽器將不會解壓縮回應。為了讓它透明地解壓縮它,你需要這樣的東西:
Content-Type: application/json
Content-Encoding: gzip
向您的 HTML 頁面添加Accept-Encoding或Content-Encoding標題(就像您所做的那樣)當然沒有效果。你應該洗掉它們。
Apache 發送的標頭取決于它的配置方式。您的服務器配置最近可能已更改。
您有 2 個解決方案:
- 修改您的 Apache 配置,以便它發送
.json.gz檔案的預期標頭 - 使用 PHP 腳本檢索壓縮的 JSON 檔案
以下是此類腳本 ( getJSON.php) 的示例:
<?php
$name = $_GET['name'];
header('Content-Type: application/json');
header('Content-Encoding: gzip');
readfile("path/to/$name.json.gz");
?>
要檢索的 URLtest.json.gz將是:
url: 'getJSON.php?name=test'
備注:如評論中所述,推薦的做法是檢查 的值$name(例如只允許字母和數字)以禁止使用../字符,這將允許攻擊者訪問.json.gz預期目錄之外的檔案。
更新
您在評論中.htaccess說包含 JSON 檔案的目錄中存在以下檔案:
<filesMatch ".(gz)$">
<ifModule mod_headers.c>
Header set Content-Encoding "gzip"
</ifModule>
</filesMatch>
該指令應發送檔案的Content-Encoding: gzip標頭.gz。但是,.htaccessApache 可能不會處理檔案,具體取決于AllowOverride
指令的值。如果AllowOverride設定為None(并且AllowOverrideList
也是None,默認情況下是這種情況),則.htaccess忽略檔案。
請注意 的默認值AllowOverride:
默認值:AllowOverride None(2.3.9 及更高版本)、AllowOverride All(2.3.8 及更早版本)
這意味著,從 Apache 2.3.9 開始,默認AllowOverride設定為None。
您在評論中說您最近升級到了 2.4.6 版本。如果AllowOverride沒有在您的 Apache 配置中明確設定,那么它解釋了為什么您的.htaccess檔案不再有效。
一種解決方案是將其添加到您的 Apache 組態檔中:
<Directory /path/to/your/json/files/>
AllowOverride All
</Directory>
uj5u.com熱心網友回復:
您可以在 ajax 回傳代碼中嘗試以下代碼:
let blob = res.data;
let reader = new FileReader();
reader.readAsDataURL(blob);
reader.onload = (e) => {
let a = document.createElement("a");
a.download = 'Your File Name';
a.href = e.target.result;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/498247.html
標籤:javascript php jQuery json 阿贾克斯
