1. 程式人生 > >IE旺旺快速登陸分析

IE旺旺快速登陸分析

IE瀏覽器上的旺旺快速登陸功能是用AliIMSSOLogin.SSOLoginCtrl.1這個ActiveX控制元件實現的。javascript訪問AliIMSSOLogin.SSOLoginCtrl.1的相關程式碼如下。

建立並初始化:

var sso = new window.ActiveXObject("AliISOLogin.SSOLoginCtrl.1");
sso.InitSSOLoginCtrl(sso.CreateSSOData(), 0);

注:AliIMSSOLogin.SSOLoginCtrl.1只能在https://login.taobao.com的頁面建立。

獲取本機已登陸旺旺或千牛的賬號列表:

var usrlist = sso.GetUserList(0, 0);

已登陸賬號的數量:

usrlist.getSize();

第i個賬號(索引從0開始)

var usr = usrlist.GetItemData(i);

賬號名:

usr.GetDataStr("strKey_ShortUserID");

快速登陸:

usr.SetDataStr("strKey_SrcURL", "http://trade.taobao.com/trade/itemlist/list_bought_items.htm"); 
sso.Go(0, usr);

需要注意的是,呼叫後,頁面會自動跳轉到https://login.taobao.com/member/loginByIm.do?XXXXXX(這裡的XXXXXX代指相關引數)。在我們自己的程式裡用WebBrowser控制元件,在BeforeNavigate2事件裡頁面攔截到這個url,並阻止WebBrowser跳轉,就可以使用這個url用來在自己程式裡登陸淘寶了。

procedure TFrmTaobaoFastLogin.WebViewBeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags,
  TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool);
begin
  OutputDebugStringW(PWideChar(WideString(URL)));


  if Pos('//login.taobao.com/member/loginByIm.do', URL) > 0 then
  begin
    FastLoginUrl := URL;
    Cancel := True;
  end;
end;

以下是完整程式碼:

uFrmTaobaoFastLogin.dfm

object FrmTaobaoFastLogin: TFrmTaobaoFastLogin
  Left = 0
  Top = 0
  Caption = #33719#21462#33258#21160#30331#38470#21442#25968
  ClientHeight = 319
  ClientWidth = 622
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  OnClose = FormClose
  PixelsPerInch = 96
  TextHeight = 13
  object WebView: TWebBrowser
    Left = 0
    Top = 0
    Width = 622
    Height = 319
    Align = alClient
    TabOrder = 0
    OnBeforeNavigate2 = WebViewBeforeNavigate2
    OnDocumentComplete = WebViewDocumentComplete
    ExplicitLeft = 304
    ExplicitTop = 160
    ExplicitWidth = 300
    ExplicitHeight = 150
    ControlData = {
      4C00000049400000F82000000000000000000000000000000000000000000000
      000000004C000000000000000000000001000000E0D057007335CF11AE690800
      2B2E12620A000000000000004C0000000114020000000000C000000000000046
      8000000000000000000000000000000000000000000000000000000000000000
      00000000000000000100000000000000000000000000000000000000}
  end
end

uFrmTaobaoFastLogin.pas

unit uFrmTaobaoFastLogin;


interface


uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, WideStrings,
  Dialogs, OleCtrls, SHDocVw, MSHTML, uOleAuto;


const
  CM_FAST_LOGIN = WM_APP + 1;
  CM_GET_USER_LIST = WM_APP + 2;


type
  TCMFastLogin = record
    MsgId: Cardinal;
    nick: WideString;
    url: PAnsiString;
    Result: Longint;
  end;


  TCMGetUserList = record
    MsgId: Cardinal;
    NickList: TStrings;
    lparam: Longint;
    Result: Longint;
  end;
  
  TFrmTaobaoFastLogin = class(TForm)
    WebView: TWebBrowser;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure WebViewBeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags, TargetFrameName,
      PostData, Headers: OleVariant; var Cancel: WordBool);
    procedure WebViewDocumentComplete(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
  private
    FastLoginUrl: AnsiString;
    Initialized: Boolean;
    function LoginUser(const nick: WideString): Boolean;
    function _GetFastLoginUrl(const nick: WideString): AnsiString;
    procedure _GetUserList(strs: TStrings);
    procedure CMFastLogin(var msgr: TCMFastLogin); message CM_FAST_LOGIN;
    procedure CMGetUserList(var msgr: TCMGetUserList); message CM_GET_USER_LIST;
  public
    procedure GetUserList(strs: TStrings);
    function IsWangwangLogined(const nick: WideString): Boolean;
    function GetFastLoginUrl(const nick: WideString): AnsiString;
  end;


var
  FrmTaobaoFastLogin: TFrmTaobaoFastLogin;


implementation


{$R *.dfm}


const BROWSER_SCRIPTS: WideString = 'var sso = new window.ActiveXObject("AliIMSSOLogin.SSOLoginCtrl.1");'
  + 'sso.InitSSOLoginCtrl(sso.CreateSSOData(), 0);'
  + 'function GetUserList(){return sso.GetUserList(0, 0);}'
  + 'function GetUser(nick){ulist=sso.GetUserList(0,1); for(i=0;i<ulist.getSize();++i){'
  + 'user = ulist.GetItemData(i); if (nick==user.GetDataStr("strKey_ShortUserID")) return user;} return null;}'
  + 'function IsUserLogined(nick){return GetUser(nick)?true:false}'
  + 'function LoginUser(nick){ulist=sso.GetUserList(0,1); for(i=0;i<ulist.getSize();++i){'
  + 'user = ulist.GetItemData(i); if (nick==user.GetDataStr("strKey_ShortUserID")){' +
  ' user.SetDataStr("strKey_SrcURL", "http://trade.taobao.com/trade/itemlist/list_bought_items.htm"); sso.Go(0, user); return true;}} return false;}';


{ TFrmTaobaoFastLogin }


procedure TFrmTaobaoFastLogin.CMFastLogin(var msgr: TCMFastLogin);
begin
  if (msgr.nick <> '') and Assigned(msgr.url) then
  begin
    msgr.url^ := Self._GetFastLoginUrl(msgr.nick);
    msgr.Result := 1;
  end
  else DefWindowProc(Self.Handle, msgr.MsgId, WPARAM(msgr.nick), LPARAM(msgr.url));
end;


procedure TFrmTaobaoFastLogin.CMGetUserList(var msgr: TCMGetUserList);
begin
  if Assigned(msgr.NickList) then
  begin
    Self._GetUserList(msgr.NickList);
    msgr.Result := 1;
  end
  else DefWindowProc(Self.Handle, msgr.MsgId, WPARAM(msgr.NickList), msgr.lparam);
end;


procedure TFrmTaobaoFastLogin.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  WebView.Stop;
end;


function TFrmTaobaoFastLogin._GetFastLoginUrl(const nick: WideString): AnsiString;
var
  msgr: MSG;
begin
  Result := '';
  FastLoginUrl := '';
  
  if not Initialized then
  begin
    WebView.Navigate('https://login.taobao.com/member/login.jhtml');
    Self.ShowModal;
  end;


  if Initialized and LoginUser(nick) then
  begin
    while not Application.Terminated and (FastLoginUrl = '') and GetMessage(msgr, WebView.Handle, 0, 0) do
    begin
      TranslateMessage(msgr);
      DispatchMessage(msgr);
    end;


    Result := FastLoginUrl;
  end;
end;


procedure TFrmTaobaoFastLogin._GetUserList(strs: TStrings);
var
  UserList: OleVariant;
  i: Integer;
begin
  if not Initialized then
  begin
    WebView.Navigate('https://login.taobao.com/member/login.jhtml');
    Self.ShowModal;
  end;




  if not Initialized then Exit;


  strs.Clear;


  if CallDispMethod((WebView.Document as IHTMLDocument2).parentWindow, GetThreadLocale, 'GetUserList', [], @UserList)
    and not VarIsNull(UserList) then
  begin
    for i := 0 to UserList.getSize - 1 do
      strs.Add(UserList.GetItemData(i).GetDataStr('strKey_ShortUserID'));
  end;
end;


function TFrmTaobaoFastLogin.GetFastLoginUrl(const nick: WideString): AnsiString;
var
  ret: DWORD;
begin
  if GetCurrentThreadId = MainThreadID then Result := _GetFastLoginUrl(nick)
  else SendMessageTimeout(Self.Handle, CM_FAST_LOGIN, WPARAM(nick), LPARAM(@Result),
    SMTO_ABORTIFHUNG or SMTO_BLOCK, 5000, ret);
end;


procedure TFrmTaobaoFastLogin.GetUserList(strs: TStrings);
var
  ret: DWORD;
begin
  if GetCurrentThreadId = MainThreadID then _GetUserList(strs)
  else SendMessageTimeout(Self.Handle, CM_GET_USER_LIST, WPARAM(strs), 0,
    SMTO_ABORTIFHUNG or SMTO_BLOCK, 5000, ret);
end;


function TFrmTaobaoFastLogin.IsWangwangLogined(const nick: WideString): Boolean;
var
  user: OleVariant;
begin
  Result := CallDispMethod((WebView.Document as IHTMLDocument2).parentWindow, GetThreadLocale, 'GetUser', [nick], @user)
    and not VarIsNull(user);
end;


function TFrmTaobaoFastLogin.LoginUser(const nick: WideString): Boolean;
var
  success: OleVariant;
begin
  Result := CallDispMethod((WebView.Document as IHTMLDocument2).parentWindow, GetThreadLocale, 'LoginUser',
    [nick], @success) and not VarIsNull(success) and BOOL(success);
end;


procedure TFrmTaobaoFastLogin.WebViewBeforeNavigate2(ASender: TObject; const pDisp: IDispatch; var URL, Flags,
  TargetFrameName, PostData, Headers: OleVariant; var Cancel: WordBool);
begin
  OutputDebugStringW(PWideChar(WideString(URL)));


  if Pos('//login.taobao.com/member/loginByIm.do', URL) > 0 then
  begin
    FastLoginUrl := URL;
    Cancel := True;
  end;
end;


procedure TFrmTaobaoFastLogin.WebViewDocumentComplete(ASender: TObject; const pDisp: IDispatch; var URL: OleVariant);
var
  ibrowser: IWebBrowser;
begin
  if Succeeded(pDisp.QueryInterface(IID_IWebBrowser2, ibrowser)) and (ibrowser = WebView.DefaultInterface) then
  begin
    if Pos('https://login.taobao.com/member/login.', URL) = 1 then
    begin
      Initialized := True;
      (WebView.Document as IHTMLDocument2).parentWindow.execScript(BROWSER_SCRIPTS, 'Javascript');
    end;
    
    Self.ModalResult := mrOk;;
  end;
end;


end.