2015-02-25 15 views
6

Tôi đã tìm thấy tất cả các loại examples về cách làm cho TWebBrowser sử dụng proxy (như 202.8.128.5:8080). Tuy nhiên tất cả các ví dụ này đang thay đổi proxy trên toàn cầu cho tất cả các phiên bản đang chạy của TWebBrowser. Tôi có hai trường hợp. Làm cách nào để đặt proxy khác nhau cho mỗi trình duyệt?Làm cách nào để đặt mỗi TWebBrowser sử dụng proxy độc lập?

+1

https://msdn.microsoft.com/en-us/library/windows/desktop/aa385328.aspx#INTERNET_OPTION_PER_CONNECTION_OPTION –

+2

Các tùy chọn này áp dụng cho API WinInet, mà ‘TWebBrowser' không sử dụng. Nó sử dụng giao diện 'IWebBrowser2' để thay thế. Mặc dù 'IWebBrowser2' là một trình bao bọc cho Internet Explorer, bản thân nó sử dụng WinInet trong nội bộ, bạn không thể áp dụng các tùy chọn WinInet cho mỗi cá thể vào' IWebBrowser2'. Chúng chỉ có thể được sử dụng khi API WinInet đang được sử dụng trực tiếp. –

+2

Điều đó quá tệ. Rất cám ơn anyway. – Beno

Trả lời

1

này có thể đạt được bằng cách sử dụng đoạn mã sau (mã công cộng, không phải của tôi):

{$DEFINE DELPHI2009_UP} 

function SetProxy(Server: String): Boolean; 
// Server z.B. '127.0.0.1:8080' oder '' 
type 
    INTERNET_PER_CONN_OPTION = record 
    dwOption: DWORD; 
    Value: record case Integer of 1: (dwValue: DWORD); 
    2: (pszValue: {$IFDEF DELPHI2009_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF}); 
    3: (ftValue: TFileTime); 
    end; 

end; 
LPINTERNET_PER_CONN_OPTION = ^INTERNET_PER_CONN_OPTION; 
INTERNET_PER_CONN_OPTION_LIST = record dwSize: DWORD; 
pszConnection: 
LPTSTR; 
dwOptionCount: 
DWORD; 
dwOptionError: 
DWORD; 
pOptions: 
LPINTERNET_PER_CONN_OPTION; 
end; 
LPINTERNET_PER_CONN_OPTION_LIST = ^INTERNET_PER_CONN_OPTION_LIST; 

const 
    INTERNET_PER_CONN_FLAGS = 1; 
    INTERNET_PER_CONN_PROXY_SERVER = 2; 
    INTERNET_PER_CONN_PROXY_BYPASS = 3; 
    INTERNET_PER_CONN_AUTOCONFIG_URL = 4; 
    INTERNET_PER_CONN_AUTODISCOVERY_FLAGS = 5; 
    PROXY_TYPE_DIRECT = $00000001; 
    PROXY_TYPE_PROXY = $00000002; 
    PROXY_TYPE_AUTO_PROXY_URL = $00000004; 
    PROXY_TYPE_AUTO_DETECT = $00000008; 
    INTERNET_OPTION_REFRESH = 37; 
    INTERNET_OPTION_PER_CONNECTION_OPTION = 75; 
    INTERNET_OPTION_SETTINGS_CHANGED = 39; 

var 
    OptionsList: INTERNET_PER_CONN_OPTION_LIST; 
    BufSize: DWORD; 
    HInternet: Pointer; 
    Agent: String; 

begin 
    Result := False; 
    BufSize := SizeOf(OptionsList); 
    OptionsList.dwSize := BufSize; 
    OptionsList.pszConnection := nil; // nil -> LAN, sonst Verbindungsname 
    OptionsList.dwOptionCount := 3; // 3 Optionen werden gesetzt 
    OptionsList.pOptions := AllocMem(3 * SizeOf(INTERNET_PER_CONN_OPTION)); 
    try 
    if not Assigned(OptionsList.pOptions) then 
     EXIT; 
    OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_FLAGS; 
    OptionsList.pOptions^.Value.dwValue := PROXY_TYPE_DIRECT or 
     PROXY_TYPE_PROXY; 
    inc(OptionsList.pOptions); 
    OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_PROXY_SERVER; 
    OptionsList.pOptions^.Value.pszValue := PChar(Server); 
    inc(OptionsList.pOptions); 
    OptionsList.pOptions^.dwOption := INTERNET_PER_CONN_PROXY_BYPASS; 
    OptionsList.pOptions^.Value.pszValue := 'local'; 
    dec(OptionsList.pOptions, 2); 
    Agent := ExtractFileName(Application.ExeName); 
    HInternet := InternetOpen 
     ({$IFDEF DELPHI2009_UP}PWideChar{$ELSE}PAnsiChar{$ENDIF} 
     (Agent), INTERNET_OPEN_TYPE_DIRECT, nil, nil, 0); 
    try // Optionen setzen 
     Result := InternetSetOption(HInternet, 
     INTERNET_OPTION_PER_CONNECTION_OPTION, @OptionsList, BufSize); 
     InternetSetOption(HInternet, INTERNET_OPTION_REFRESH, nil, 0); 
    finally 
     InternetCloseHandle(HInternet); 
    end; 
    finally 
    FreeMem(OptionsList.pOptions); // Speicher freigeben 
    end; 
end; 
  • Drop haiTWebBrowser thành phần vào mẫu của bạn và haiTButton
  • TWebBrowser thành phần sẽ có tên mặc định WebBrowser1WebBrowser2
  • Hai TButton sẽ có tên mặc định Button1Button2
  • Thêm WinInet quy định tại khoản uses bạn

Gọi chức năng trên trong Button1

Mã cho Button1OnClick sự kiện:

procedure TForm1.Button1Click(Sender: TObject); 
begin 
SetProxy('ip:port'); 
WebBrowser1.Navigate('www.whatismyipaddress.com'); 
end; 

Mã cho Button2OnClick sự kiện:

procedure TForm1.Button2Click(Sender: TObject); 
begin 
SetProxy('ip:port'); 
WebBrowser2.Navigate('www.whatismyipaddress.com'); 
end; 

Và đây là cách có vẻ:

enter image description here

Bên trái là WebBrowser1 với một proxy và bên phải là WebBrowser2 với một proxy khác nhau - cả hai trình duyệt đều nằm trong cùng một ứng dụng và dường như chúng hoạt động. Tôi cũng đã truy cập địa chỉ từ trình duyệt thông thường của mình (Chrome) trong khi ứng dụng đang chạy và nó thực sự xuất hiện khi sử dụng kết nối ban đầu của tôi.

Vì vậy, nó hoạt động. Các thành phần WebBrowser đang sử dụng proxy được chỉ định của họ trong khi trình duyệt trên máy của tôi vẫn không bị ảnh hưởng (không sử dụng một trong hai proxy)

Thử nghiệm điều này bằng Rad Studio 10.2 Tokyo ngay bây giờ. Chúc may mắn :)

CẬP NHẬT

Như đã nhấn mạnh trong các ý kiến, một cách để thiết lập proxy sẽ được sử dụng để di chuyển, mà không đặt nó lúc thiết kế hoặc trong nút bạn sử dụng để Navigate là bằng cách sử dụng một số TStringList và tải nó từ một tệp (ví dụ .txt). Điều này có thể được sử dụng trong các sự kiện TWebBrowserOnBeforeNavigate2sự kiện.

procedure TForm1.WebBrowser1BeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool); 

var 
proxylist: TStringList; 

begin 
proxylist:= TStringList.Create; 
proxylist.LoadFromFile('proxylist.txt'); 
SetProxy(proxylist.Strings[0]); //adds the proxy from the 1st line in the txt 
proxylist.Free; 
end; 

Tạo tệp .txt có tên proxylist trong thư mục ứng dụng của bạn và viết proxy tại đó.

Bây giờ, bạn sẽ có một bộ proxy cho TWebBrowser trước khi bắt đầu điều hướng. Dù bằng cách nào, tôi chắc chắn có rất nhiều cách để mở rộng điều này để sử dụng trí tưởng tượng của bạn.

+1

Điều gì xảy ra nếu bạn thêm nút thứ ba gọi là 'Điều hướng()' trên cả hai điều khiển trình duyệt mà không cần đặt proxy trước? Tôi đã không thử nghiệm nhưng giả định rằng điều này sẽ chứng minh rằng hai trường hợp trình duyệt không thực tế sử dụng proxy độc lập nhưng chỉ là phiên bản cuối cùng được thiết lập. – mghie

+0

@mghie Câu hỏi đặt ra là làm thế nào để bạn thiết lập một proxy khác nhau cho mỗi 'TWebBrowser' mà không thay đổi thiết lập chung trên hệ thống hoặc lẫn nhau. Bạn có thể đặt proxy trong sự kiện 'TWebBrowser'' OnBeforeNavigate2', hoặc tại thời điểm thiết kế hoặc bằng cách sử dụng TStringList và tải một proxy từ một danh sách .txt/.ini trong thư mục chương trình, cho biết dòng nào cần tải, lặp chúng và v.v. Tôi vừa thử nghiệm và tôi có thể xác nhận phương pháp này cũng hoạt động và giúp bạn giải quyết vấn đề, bạn có thể điều hướng một cách tự do sau khi thiết lập của nó bằng cách sử dụng sự kiện. – Petzy

Các vấn đề liên quan