WebBrowser и редирект
От: east  
Дата: 14.05.09 06:29
Оценка:
Всем привет!
Вопрос такой, как узнать url сайта на который происходит редирект, до того как WebBrowser обработает редирект и начнет загружать эту страницу?
Re: WebBrowser и редирект
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 14.05.09 06:42
Оценка:
Здравствуйте, east, Вы писали:

E>Вопрос такой, как узнать url сайта на который происходит редирект, до того как WebBrowser обработает редирект и начнет загружать эту страницу?


Курить в MSDN DWebBrowserEvents2::BeforeNavigate2.
Re[2]: WebBrowser и редирект
От: east  
Дата: 14.05.09 06:51
Оценка:
Здравствуйте, Flamer, Вы писали:

F>Курить в MSDN DWebBrowserEvents2::BeforeNavigate2.


Пробовал. Не ловит. Хотя может, что-то хитрое нужно сделать. Если не трудно, напишите, пожалуйста, подробней.
Re[2]: WebBrowser и редирект
От: Tilir Россия http://tilir.livejournal.com
Дата: 14.05.09 11:22
Оценка:
Здравствуйте, Flamer, Вы писали:

E>>Вопрос такой, как узнать url сайта на который происходит редирект, до того как WebBrowser обработает редирект и начнет загружать эту страницу?


F>Курить в MSDN DWebBrowserEvents2::BeforeNavigate2.


Совершенно точно не ловит. Я в своё время исследовал этот вопрос весьма подробно. У меня есть страничка http://tilir.6te.net/redirect.html, которая перебрасывает на www.google.com

Вот простенький код для воспроизведения:

#include <windows.h>
#include <exdisp.h>
#include <exdispid.h>
#include <atlbase.h>
#include <atlcom.h>
#include <mshtml.h>
#include <string>
#include <iostream>

class CEventHandler : public DWebBrowserEvents2 {
public:
  STDMETHODIMP QueryInterface(REFIID riid, void** ppv){
      *ppv = NULL;
      if (IsEqualGUID(riid, IID_IUnknown)){
        *ppv = (IUnknown *)this;
      }    
      if (IsEqualGUID(riid, IID_IDispatch)){
        *ppv = (IDispatch *)this;
      }
      if (IsEqualGUID(riid, __uuidof(DWebBrowserEvents2))){
        *ppv = (DWebBrowserEvents2 *)this;
      }
      if (*ppv) {
          ((IUnknown *)(*ppv))->AddRef();
          return S_OK;
      }
    return E_NOINTERFACE;
  }

  STDMETHODIMP_(ULONG) AddRef(){
    return InterlockedIncrement(&counter);
  }
  
  STDMETHODIMP_(ULONG) Release(){
      if (InterlockedDecrement(&counter) <= 0) {
        return 0;
      }
      return counter;    
  }
  
  STDMETHODIMP GetTypeInfoCount(UINT *pctinfo){
      *pctinfo = 0;
      return E_NOTIMPL;  
  }
  
  STDMETHODIMP GetTypeInfo(UINT /*iTInfo*/, LCID /*lcid*/, ITypeInfo** ppTInfo){
      *ppTInfo = NULL;
      return E_NOTIMPL;
  }
  
  STDMETHODIMP GetIDsOfNames(REFIID /* riid */, LPOLESTR* /* rgszNames */, UINT /* cNames */, LCID /* lcid */, DISPID* /* rgDispId */){
    return S_OK;
  }
  
  STDMETHODIMP Invoke(DISPID dispIdMember, REFIID /* riid */, LCID /* lcid */, WORD /* wFlags */, DISPPARAMS *pDispParams, VARIANT* /*pVarResult*/, EXCEPINFO* /* pExcepInfo */, UINT* /* *puArgErr */){
    int ndispid = dispIdMember;
    std::cout << "dispid = " << std::dec << ndispid << std::endl;
    if (DISPID_BEFORENAVIGATE2 == dispIdMember){
      int order = 7;      
      LPCWSTR wcsNav = pDispParams->rgvarg[order - 2].pvarVal->bstrVal;       
      std::wcout << L"navigate detected to: " << wcsNav << std::endl;      
    }
    return S_OK;
  }
private:
    volatile long counter;
};

bool checkRedirect(const wchar_t *wcsUrl){
  CComPtr<IWebBrowser2> webBrowser;
  HRESULT hr = webBrowser.CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER);
  hr = webBrowser->put_Visible(VARIANT_TRUE);
  
  CComQIPtr<IConnectionPoint> conn;
  CEventHandler handler;
  DWORD dwConnectionCookie;  
  
  CComQIPtr<IConnectionPointContainer> cp_container;    
  cp_container = webBrowser;
    hr = cp_container->FindConnectionPoint(DIID_DWebBrowserEvents2, &conn);
    CComPtr<IUnknown> unk;
    handler.QueryInterface(IID_IUnknown, (void**)&unk);
    conn->Advise(unk, &dwConnectionCookie);
  
  CComVariant vEmpty;  
  hr = webBrowser->Navigate(CComBSTR(wcsUrl), &vEmpty, &vEmpty, &vEmpty, &vEmpty);
  
  for(;;){
      VARIANT_BOOL vtb = VARIANT_TRUE;
      hr = webBrowser->get_Busy(&vtb);
      if (FAILED(hr) || (VARIANT_FALSE == vtb)){
        break;
      }
    }
    
    return false;
}

int main(int argc, char** argv){
  std::locale::global(std::locale(""));
  HRESULT hr = ::CoInitialize(NULL);
  std::cout << "CoInitialize with HR = " << std::hex << hr << std::endl;
  
  checkRedirect(L"http://tilir.6te.net/redirect.html");
  
  ::CoUninitialize();
  return 0;
}


Выводит вот такую статистику по DISPID'ам

[quote]
CoInitialize with HR = 0
dispid = 112
dispid = 250
navigate detected to: http://tilir.6te.net/redirect.html
dispid = 106
dispid = 112
dispid = 105
dispid = 105
dispid = 102
dispid = 108
dispid = 102
dispid = 102
dispid = 108
dispid = 102
dispid = 102
dispid = 270
dispid = 104
dispid = 102
dispid = 106
[/quote]

Коды можно посмотреть в exdispid.h, там ничего интересного. И переход на google.com не случается хотя по факту в конце мы уже там.

Я в своё время плюнул на это сделал воркэраунд, а теперь раз уж тема есть предлагаю на общее обсуждение.
Re[3]: WebBrowser и редирект
От: east  
Дата: 14.05.09 17:08
Оценка:
Здравствуйте, Tilir.

Большое спасибо. Буду разбираться.
Re[4]: WebBrowser и редирект
От: villy  
Дата: 17.05.09 14:09
Оценка:
Здравствуйте, east, Вы писали:

E>Здравствуйте, Tilir.


E>Большое спасибо. Буду разбираться.



есть много вариантов редиректов.
Можно отлавливать 302, 303 там befornavigate , i navigatecompleate получаеш разные пути.

а через location, метаревреш, можно чрез флеш делать редирект,
через iwebbroser их не провериш, тк идет полная загрузка страницы.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.