問題描述
在微軟雲端儲存賬號的服務中,儲存一些靜態圖片,然後透過App Service訪問,但是遇見了400 - condition headers not support 錯誤。
在單獨透過瀏覽器訪問 File Share中的檔案,發現第一次可以請求成功,但是第二次重新整理後就遇見400錯誤,第三次重新整理的時候又訪問成功,如此迴圈下去。
錯誤訊息為:
This XML file does not appear to have any style information associated with it. The document tree is shown below.
<Error> <Code>ConditionHeadersNotSupported</Code> <Message>Condition headers are not supported. RequestId:cf7f3c6e-101a-0052-73db-ea03cf000000 Time:2023-09-19T09:24:55.3527405Z</Message> </Error>
問題解答
在網路上搜尋關鍵字 “400 Condition headers are not supported. “, 就可以發現很多結果。
其中以 Github的結果(https://github.com/MicrosoftDocs/azure-docs/blob/main/includes/storage-files-condition-headers.md) 和 Stack Overflow (https://stackoverflow.com/questions/43706605/azure-file-storage-error-condition-headers-are-not-supported) 為參考,找到了問題的根源
根源
Conditional headers aren't currently supported. Applications implementing them will need to request the full file every time the file is accessed.
Storage Account 目前不支援條件標頭。 實現它們的應用程式將需要在每次訪問檔案時請求完整的檔案。
文章中也給出瞭解決方案,透過在上傳的檔案中設定 CacheContorl屬性值為 no-cache, no-store, must-revalidate. 目的時告訴瀏覽器,不要對這個URL的內容進行快取,必須從源站點重新驗證獲取最新資源。
- 所以需要透過 Azure Storage Explorer工具對每一個檔案(注意:不能對檔案所屬的資料夾進行修改)的屬性值 【CacheControl】進行修改。
- 在Stack Overflow中,提出了另一種解決辦法,就是在每一次請求的URL後面,增加一個隨機引數,以保證每次發出的請求URL不一樣,避免了瀏覽器快取,因此也不會新增 Conditional Header。
經驗證,這種方法是可行的。
但問題在於,這個方法也只能使用一次。
第二次重新整理時(如果隨即引數不變化),也會遇見400-condition headers not support報錯。
所以最後,最好的解決辦法還是在Azure Blob File Share的檔案中,新增屬性值 CacheContorl為 no-cache, no-store, must-revalidate。
- 如果是新檔案,可以在上傳的方法中設定CacheControl Properties 。
- 如果是已經存在的檔案,可以透過PowerShell指令碼批次修改檔案的 CacheControl Properties, 主要是使用
1) 獲取指定folder下的全部內容 az storage file list
2) Foreach 迴圈,如果遇見資料夾,使用遞迴呼叫,直至全部檔案獲取完畢
3) 對檔案型別,使用 az storage file update 更改 --content-cache 值
PowerShell指令碼示例如下:
## Set the Storage Account name, File Share Name, and the Acceount Key $account_name = "您的儲存賬號名稱" $account_key = "您的儲存賬號金鑰" $file_share_name = "需要修改的資料夾名稱" #會修改資料夾中所有檔案的content-cache屬性值為 "no-cache, no-store, must-revalidate" ## Recursive Call to list all files and update the file properties . Function UpdateAllFileProperties { param($foldername) Write-Host "Start to list this folder - " $foldername #List all file & folder under this input folder path... $subfiles = az storage file list -s $foldername --account-name $account_name --account-key $account_key | ConvertFrom-Json Foreach ($f in $subfiles) { If ($f.type -eq 'file') { Write-Host "\t" + $f.name #Update file properties --content-cache "no-cache, no-store, must-revalidate" az storage file update -p $f.name -s $foldername --account-name $account_name --account-key $account_key --content-cache "no-cache, no-store, must-revalidate" } elseif ($f.type -eq 'dir') { $newfolder = $foldername + '/' + $f.name Write-Host $newfolder UpdateAllFileProperties $newfolder } else { Write-Host "Invalid type, coutinue ... " } } } Write-Host "Start ... " #Start to foreach all files & folders UpdateAllFileProperties $file_share_name Write-Host "Complete ... "
執行結果展示動畫:
參考資料
Error ConditionHeadersNotSupported from a Web Application using Azure Files from Browser : https://github.com/MicrosoftDocs/azure-docs/blob/main/includes/storage-files-condition-headers.md
Azure File Storage Error: Condition Headers Are Not Supported : https://stackoverflow.com/questions/43706605/azure-file-storage-error-condition-headers-are-not-supported
az storage file : https://learn.microsoft.com/en-us/cli/azure/storage/file?view=azure-cli-latest#az-storage-file-list()
Cache-Control : https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control