修改UIWebView的UserAgent,解決__doPostBack無法產生的問題

透過UIWebView修改UserAgent,解決__doPostBack無法產生的問題

今天下午被同事問到一個很好玩的問題,由於部門撰寫的網頁均是用ASP.NET程式來開發,因此在iPhone閱讀的時候,

有時候會遇到JavaScript沒有被載入或是CSS功能失效的問題。但這樣的問題卻在iPhone 3GS裡不會出現,只會出現在

iPhone 4新的iOS之後,甚至連ASP.NET最需要的__doPostback的javascript都沒有產生至網頁的HTML之中。

 

這下子好了,沒有了__doPostback的Javascript,很多控件(例如:GridView、LinkButton等集合元件)需要透過javascript

來觸發後端事件的功能均沒有辦法實現。但是也許你會發現,透過Safari瀏覽ASP.NET網頁是不會有問題的,只有在透過實

作的App裡內嵌UIWebView控件後,無法出現__doPostback的事件才會明顯被遇到。

 

至於這樣的問題要怎麼來解決?究竟是ASP.NET的問題還是iOS在UIWebView的支援度的問題呢?

根據<ASP.NET 4.0 issue with BrowserCap incorrectly detecting UIWebView (Safari) in iOS>這一篇的討論串裡,它的主題是:

「ASP.NET 4.0 has an issue where it incorrectly determines browser capabilities for Safari on iPhone 4.2.1.

ASP.NET determines that this browser does not support javascript and does not include __doPostBack function

to handle postbacks which causes javascript errors. This behavior is incorrect since Safari browser does support javascript.」

是不是很接近所要尋找的問題點呢?根據裡面的討論串可以歸納出問題點:

 

a. ASP.NET支援的Browser Type(App_Browsers)

b. IIS支援的Browser Type (ASP.NET 2.0/ASP.NET4.0)

 

這二個問題就是整個問題的最重要關鍵,由於App_Browsers支援Browser Type的項目,針對iPhone 4.2.1在UIWebView裡內

鍵送出的User Agent識別程度是相對過去而言是比較低的,也造成ASP.NET或IIS無法識別出是否要產生__doPostback的參數,

甚至連一些必要的隱藏欄位也沒有被產生,如下:

   1: //ASP.NET運作事件的必要元素,遇到iOS送出的User Agent卻沒有產生
   2: <div class="aspNetHidden">
   3: <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
   4: <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
   5: <input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
   6: <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwUKMTc3NTkxNjQxMmQYAgUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgkFCkNXQmFjayRidG4FE0ltYWdlQnV0dG9uSG9tZSRidG4FIUluQm94TGlzdCRBZHZHcmlkVmlldyRjdGwwMiRjdGwwMQUhSW5Cb3hMaXN0JEFkdkdyaWRWaWV3JGN0bDAzJGN0bDAxBSFJbkJveExpc3QkQWR2R3JpZFZpZXckY3RsMDQkY3RsMDEFIUluQm94TGlzdCRBZHZHcmlkVmlldyRjdGwwNSRjdGwwMQUhSW5Cb3hMaXN0JEFkdkdyaWRWaWV3JGN0bDA2JGN0bDAxBStJbkJveExpc3QkSW5Cb3hMaXN0X0J0bkdyaWRWaWV3UHJldlBhZ2UkYnRuBStJbkJveExpc3QkSW5Cb3hMaXN0X0J0bkdyaWRWaWV3TmV4dFBhZ2UkYnRuBRVJbkJveExpc3QkQWR2R3JpZFZpZXcPPCsADAEIAgFk" />
   7: </div>
   8:  
   9: //ASP.NET運作事件的必要元素,遇到iOS送出的User Agent卻沒有產生
  10: <script type="text/javascript">
  11: //<![CDATA[
  12: var theForm = document.forms['form1'];
  13: if (!theForm) {
  14:     theForm = document.form1;
  15: }
  16: function __doPostBack(eventTarget, eventArgument) {
  17:     if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
  18:         theForm.__EVENTTARGET.value = eventTarget;
  19:         theForm.__EVENTARGUMENT.value = eventArgument;
  20:         theForm.submit();
  21:     }
  22: }
  23: //]]>
  24: </script>

 

了解原由後,那就來看看要怎麼解決這樣的問題吧。

由於User Agent無法識別的原因,那麼就設定一個通用可以支援ASP.NET或IIS識別的User Agent參數。

〉修改UIWebView的User Agent

由於UIWebView不支援直接修改User Agent,所以改為透過直接覆寫NSMutableURLRequest元件的User-Agent,讓每次UIWebView

都可以使用修改過的User Agent來發送給指定的Web Server取得正確的JavaScript與CSS。

但由於每次都要修改NSMutableURLRequest的User Agent很不方便,透過該<Easily set the User-Agent in a UIWebView | MPHWeb >篇

的介紹,它提供直接在init時就讓UIWebView取得設定,這樣就不需每次都修改啦。

如以下的範例:

   1: //設定UserAgent參數,綁定在每次UIWebView的Request中使用
   2:  
   3: NSDictionary *dictionnary = [[NSDictionary alloc] initWithObjectsAndKeys:
   4:     @"Mozilla/5.0 (iPhone; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/4.0 Mobile/8C148 Safari/528.16", 
   5:     @"UserAgent", nil];
   6:     [[NSUserDefaults standardUserDefaults] registerDefaults:dictionnary];
   7:     [dictionnary release];

User Agent的參數:

Mozilla/5.0 (iPhone; U; CPU OS 4_2_1 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/4.0 Mobile/8C148 Safari/528.16

 

======

感謝這個問題的提供者 - 白菜,由它提出了這樣問題的需求,所以才有機會讓我找到解決的方式來解開這樣的問題。

該篇文章是針對他的問題加以整理並且加上他對這方面的建議,說明為何透過iOS裡的UIWebView讀取ASP.NET網頁時,

卻沒有產生__doPostback的問題。希望有所幫助。謝謝。

 

References:

ASP.NET 4.0 issue with BrowserCap incorrectly detecting UIWebView (Safari) in iOS (問題的原由)

Programmatically fill in data in a UIWebview

Easily set the User-Agent in a UIWebView | MPHWeb (必讀)

iPhone/iPad – Get User-Agent for UIWebView

Change User Agent in UIWebView (iPhone SDK)

 

Dotblogs Tags: