我需要導航到最終包含.pdf文件的網站,並且我想在本地保存該文件。我正在使用CEFSharp來執行此操作。這個網站的性質是這樣的,一旦.pdf出現在瀏覽器中,它不能被再次訪問。出於這個原因,我想知道如果瀏覽器中顯示了.pdf,是否有方法可以訪問緩存中該文件的源代碼?從CEFSharp中的緩存中讀取文件
我已經嘗試過實現IDownloadHandler並且可以工作,但是您必須單擊嵌入式.pdf上的保存按鈕。我試圖解決這個問題。
我需要導航到最終包含.pdf文件的網站,並且我想在本地保存該文件。我正在使用CEFSharp來執行此操作。這個網站的性質是這樣的,一旦.pdf出現在瀏覽器中,它不能被再次訪問。出於這個原因,我想知道如果瀏覽器中顯示了.pdf,是否有方法可以訪問緩存中該文件的源代碼?從CEFSharp中的緩存中讀取文件
我已經嘗試過實現IDownloadHandler並且可以工作,但是您必須單擊嵌入式.pdf上的保存按鈕。我試圖解決這個問題。
好的,這是我如何得到它的工作。 CEFSharp中有一個功能,允許您過濾傳入的Web響應。因此,這使您可以完全訪問傳入流。我的解決方案有點骯髒的一面,並不是特別有效,但它適用於我的情況。如果有人看到更好的方法,我很樂意提供建議。爲了讓我的代碼正常工作,我必須假設兩件事。
開始與CEF小例子,在這裏找到:https://github.com/cefsharp/CefSharp.MinimalExample
我用的WinForms版本。實施IRequestHandler和IResponseFilter表單定義如下:
public partial class BrowserForm : Form, IRequestHandler, IResponseFilter
{
public readonly ChromiumWebBrowser browser;
public BrowserForm(string url)
{
InitializeComponent();
browser = new ChromiumWebBrowser(url)
{
Dock = DockStyle.Fill,
};
toolStripContainer.ContentPanel.Controls.Add(browser);
browser.BrowserSettings.FileAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.UniversalAccessFromFileUrls = CefState.Enabled;
browser.BrowserSettings.WebSecurity = CefState.Disabled;
browser.BrowserSettings.Javascript = CefState.Enabled;
browser.LoadingStateChanged += OnLoadingStateChanged;
browser.ConsoleMessage += OnBrowserConsoleMessage;
browser.StatusMessage += OnBrowserStatusMessage;
browser.TitleChanged += OnBrowserTitleChanged;
browser.AddressChanged += OnBrowserAddressChanged;
browser.FrameLoadEnd += browser_FrameLoadEnd;
browser.LifeSpanHandler = this;
browser.RequestHandler = this;
宣言和最後兩行是對此的解釋是最重要的。我實現了使用模板的IRequestHandler這裏找到: https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Example/RequestHandler.cs 我改變了一切,以什麼建議,除了對GetResourceResponseFilter默認我實現如下:
IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response)
{
if (request.Url.EndsWith(".pdf"))
return this;
return null;
}
然後我實現IResponseFilter如下:
FilterStatus IResponseFilter.Filter(Stream dataIn, out long dataInRead, Stream dataOut, out long dataOutWritten)
{
BinaryWriter sw;
if (dataIn == null)
{
dataInRead = 0;
dataOutWritten = 0;
return FilterStatus.Done;
}
dataInRead = dataIn.Length;
dataOutWritten = Math.Min(dataInRead, dataOut.Length);
byte[] buffer = new byte[dataOutWritten];
int bytesRead = dataIn.Read(buffer, 0, (int)dataOutWritten);
string s = System.Text.Encoding.UTF8.GetString(buffer);
if (s.StartsWith("%PDF"))
File.Delete(pdfFileName);
sw = new BinaryWriter(File.Open(pdfFileName, FileMode.Append));
sw.Write(buffer);
sw.Close();
dataOut.Write(buffer, 0, bytesRead);
return FilterStatus.Done;
}
bool IResponseFilter.InitFilter()
{
return true;
}
我發現的是,PDF實際上是下載兩次,當它被加載。無論如何,可能會有頁眉信息和頁面開頭的內容。當我得到以%PDF開頭的流段時,我知道它是PDF的開始,所以我刪除該文件以放棄可能存在的任何以前的內容。否則,我只是將每個段附加到文件的末尾。從理論上講,PDF文件在您導航到另一個PDF文件之前是安全的,但我的建議是在頁面加載後立即對文件執行某些操作以保證安全。
完美的解決方案 –
'CEF'沒有提供訪問'cache'的方法(你可能直接讀取'db',儘管我從未嘗試過)。你可以實現一個'ResourceHandler'並自己下載文件,並在本地進行緩存。根據您使用的分支,「ResourceHandler」的實現稍有不同。請參閱https://github.com/cefsharp/CefSharp/blob/cefsharp/49/CefSharp.Example/FlashResourceHandler.cs#L22應該是一個起點,如果您使用舊版本,只需切換分支以查看不同的版本。 – amaitland
我在使用.Net WebBrowser的這個項目的早期版本中嘗試了這種方法。我碰到的問題是,創建的HTMLRequest沒有cookies或任何安全信息來訪問.pdf。有沒有辦法將瀏覽器中緩存的安全信息傳遞給HTMLRequest? –
我想你可以查詢cookie存儲,雖然這變得越來越複雜。還有另一種選擇,雖然很新,並沒有特別好的測試。見https://github.com/cefsharp/CefSharp/pull/1519 – amaitland