[TITANIUM] 在android中的webview取得cookie

LINEで送る
[`evernote` not found]

雖然titanium一向號稱可以使用同樣的程式碼同時製作出android跟ios的app,但實際上事情總不是這麼的歡樂….
像是一個簡單的是用twitter帳號來進行登入的動作,由於api的工程師是使用cookie跟CSRF token配對好的金鑰來跟api端進行認證,ios因為webview跟HTTPClient會自動共用cookie,所以只要在webview登入twitter後,就可以以新建立的HTTPClient來跟api索取token然後進行跟api端的互動。
只是到了android的時候,webview與HTTPClient不再自動共用cookie,所以我們得要在HTTPClient把object傳送到api之前利用setRequestHeader帶入Cookie,才有辦法取得正確的token。
所以問題就在於怎麼在登入成功的webview中,取出當時的cookie。接著google會告訴我們在這邊有這麼一個方法:

webView.addEventListener('load',function(e) {
  var cookies = webView.evalJS("document.cookie").split(";"); 
  Ti.API.info( "# of cookies -> " + cookies.length  );
  for (i = 0; i <= cookies.length - 1; i++) {
    Ti.API.info( "cookie -> " + cookies[i] );
  }
});

可惜我所得到的卻始終是空值(NULL)。

但其實這個方法原來還是是對的,原因出在系統的登入成功頁面中的cookie被設下了「httponly」這個參數。所以雖然我們可以利用工具來讀到正確的cookie但是卻無法透過evalJS的方法得到cookie!!
所以在請系統方的工程師拿掉httponly參數後,就順利的取得了我們所需要的cookie,然後在使用HTTPClient:

function doXHR(callback, seedObj, api, method) {
	Ti.App.fireEvent("loading:lock");	
	var xhr = Titanium.Network.createHTTPClient({
		autoEncodeUrl: false
	});
	var dialog = Ti.UI.createAlertDialog({
		buttonNames : ['Try again','Cancel'],
		title : 'ERROR'
	});
	dialog.addEventListener('click', function(e) {
		if(e.index == 0)
		doXHR(callback, seedObj, api, method);
	});
	xhr.setTimeout(30000);
	xhr.onerror = function(e) {
		Ti.App.fireEvent("loading:unlock");
		Ti.API.info('IN ERROR ' + e.error);
		dialog.message = '「'+api + '」 with ERROR :' + e.error+"@status: "+xhr.status;
		dialog.show();
	};
	xhr.onload = function(e) {
		Ti.App.fireEvent("loading:unlock");
		var res = JSON.parse(this.responseText);
		callback(res);
	};
	xhr.onsendstream = function(e){
	    Ti.API.info('ONSENDSTREAM - PROGRESS: ' + e.progress);
	};
	var getway = prop.get('utilsURL') + api;
	xhr.open(method, getway);
 
	var cookie = prop.get('cookie');
	if (cookie !== null && cookie !== '' && cookie !== undefined) {
		cookie = cookie.replace(/;.+/, ';');
		xhr.setRequestHeader('Cookie',cookie);
    }
	xhr.send(seedObj);
}