顯示具有 F2E 標籤的文章。 顯示所有文章
顯示具有 F2E 標籤的文章。 顯示所有文章

2015年6月3日 星期三

【往F2E這個路子走】jQuery - .ajax 方法遇到 CORS (cross origin request sharing) 問題

今天看書想說學著人家書上用jQuery來呼叫遠端Service,
又正好一直想學 WebAPI 以後好找工作,
所以就決定要來嘗試用jQuery連接遠端 WebAPI取回資料,
也心想早在多年前我玩 PhoneGap 也用過 jQuery的ajax取service資料,
應該沒啥難度吧!!

霸特, 永遠在心想說很簡單時就會總有這個霸特, 我遇到了我解決不了的問題啊啊啊啊啊!!!!!

好的,
讓我娓娓道來這個問題發生的情境吧!!

首先
我很簡單的寫了一個html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript">
      $(document).ready(function(){
        $('a').click(function(event){
          event.preventDefault();
          $.ajax({
            url:'http://localhost:58501/api/Values',
            success:function(data){alert('success');},
            error:function(xhr){alert('error');}
          });
        });
      });
    </script>
  </head>
  <body>
    <div>
      <h3>CORS TESTING</h3>
      <a href="#">Click Me!!</a>
    </div> 
  </body>
</html>
P.S. 我的Web API 就是當你在建立Web API專案時最原始的那個Values API, 然後在本機執行時我的port是58501。

就當我點下 Click Me連結覺得說就會很自然的像是每個人每天都需要喝水一樣的自然會跳出訊息框跟我說 : success
但是我卻得到了個 error !!!!

後來我用FireBug去查了查揪竟是怎麼個一回事兒啊
得到了下圖:
李組長他是眉頭一皺發現案情不太單純
我明明就是在本地端localhost 而且我腿很短怎麼可能會有跨網域問題勒?


後來股溝了一下才知道
原來不同的port就算是跨網域了啦
HTML網頁放在原生的localhost (C:/inetpub/wwwroot/)底下
Web API則是透過Visual Studio的虛擬伺服器幫我在localhost:58501底下執行
所以就算是跨網域存取嚕....

然而了解目前的這個摸們的狀況後
剩下要解決的就是怎樣可以讓我的網頁跨網域存取啊?
基本上來說這個所謂CORS狀況是出現在javascript才會有的
因為從前從前有一批壞蛋喜歡用跨網域攻擊別人
所以javascript就開始不能存取跨網域的資源啦
那可好了
我們通常要用ajax就是想說可以背後偷偷來跟人家說一些五四三的
如果不能跨網域存取那不就自廢武功了啊啊啊啊啊啊啊

因此在一番妥協之後
最後演變成如果你允許哪個網站存取你的資源
那就自己設定開放囉
重點就是你要在header裡面註明要開放給誰, 也就是設定'Access-Control-Allow-Origin'的內容 (允許哪個來源網站存取我的資源)
也就是上圖中他跟你說我的網頁沒檔頭這件事....(咦?)

好吧
其實這問題出在說Web API那端沒有給我權限去存取它的資源
也就是說我必須去修改Web API就是了

所以我就去找了找網路文章看要怎麼樣去修訂我的Web API讓他可以允許我跨網域存取
原來也就很簡單
只要去NuGet下載相關dll library之後進行引用
然後在你要開啟的Web API方法上面加註屬性即可唷!!
步驟如下:

(1). 先去NuGet Search "CORS", 然後Install "Microsoft ASP.NET Web API 2.2 Cross-Origin Support"這個套件

(2). 安裝好之後其實你就可以看到專案中的References已經加入了System.Web.Http.Cors這個命名空間的dll囉 !!

















(3). 焦點跳到WebApiConfig.cs上面, 在Register方法中加入 config.EnableCors(); 讓Web API 可以允許設定Cross Origin Request Sharing功能


(4). 最後回到我們要提供開放跨網域存取的Web API方法 (本例中就是去ValuesController.cs檔案)上面去加註此方法開放跨網域存取唷!! 另外記得要先引入System.Web.Http.Cors命名空間唷!!!

(5). 回頭我們再測一下網頁吧~perfect !!!! :D

以上就是簡單介紹一下在jQuery要用ajax方法去呼叫遠端Web API遇到CORS的解決方式,
不過也看出來其實問題都不是呼叫端,
都還是要去改伺服器端才行啊~

此外上面去設置[EnableCors]的屬性中可以置入三個參數,
分別是用於設置CORS的作用範圍
依序為 :
(1). Action
(2). Controller
(3). Global
影響層面應該是由內而外這樣
大家可以自行參考一下下面的Reference囉~

以上, 謝謝收看嚕~

【Reference】
(1). http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
(2). http://blogs.msdn.com/b/msdntaiwan/archive/2013/09/10/asp-net-web-api-2.aspx



後續補充】
後來陸續又看了一些影片介紹Web API的時候
發現其實早在很久很久很久很久以前人家就講解過這個議題了
所以其實我算是後知後覺啦
但這其實不是重點
重點是他有另一個設定方式
不是在Controller裡的Action上面加Attribute唷
而是寫在Web.Config檔案裡面
但是但是
這樣的做法是屬於全域性的修改作法喔
大家也還是要小心注意這樣的唷
設定範例如下:
<system.webserver>
    <httpprotocol>
        <customheaders>
            <add name="Access-Control-Allow-Origin" value="*" />
            ......
        </customheaders>
    </httpprotocol>
</system.webserver>


簡單的說也就是全域的WebAPI都加上Access-Control-Allow-Origin=*這個檔頭就是嚕

【Reference】
 http://www.microsoftvirtualacademy.com/training-courses/developing-web-services-using-aspnet-webapi2

2015年4月20日 星期一

【往F2E這個路子走】Media Queries - Part 1

Media Queries 是 Responsive Design的核心所在,
倘若沒有Media Queries,
那CSS大概就沒辦法讓我們搞出這麼多花樣來迎合使用者需求嚕~
所以咱門來好好學習一下吧!!

 Media Queryies基本上分成兩個部分:Media TypesMedia Expression。 

先說說Media Types吧!
其實早期在CSS2.1 (現在我們都用CSS3.0)的時候,
就已經有定義多達10種的Media Types囉!(我完全不知道這件事...糗
而一般通常我們常常遇到的有三種:all, screenprint。(為啥我覺得我也沒常常遇到...畢竟之前是稿後端的關係?

以前的設定基本上就是定義在我們的CSS連結標記中,
像是以下的寫法:
<link rel="stylesheet" type="text/css" href="all.css" media="all" />
<link rel="stylesheet" type="text/css" href="screen.css" media="screen" />
<link rel="stylesheet" type="text/css" href="print.css" media="print" />

或者是說我們把print設定在CSS file裡面這樣:
@media print {
        /*  print styles go here  */
}

那這樣把Media Types定義好事有啥好處哩?
好處不外乎是:讓人家知道好處理不用在那裏猜猜猜啊啊啊啊~
Media Types先設定好可以減少額外的HTTP requests,
所以就會讓網頁的執行效率上更為提升,
但若你要問我為啥會減少HTTP requests?
抱歉書上沒說我也不知道....(真糟)
總之就先知道就好咩....

而且而且啊,
如果先設定好Media Types向上面一樣把它分開來多個檔案,
就可以不用下載其他一堆不相關的CSS設定,
阿捏不是非常之好咩~?
就像是你要Mobile device下載print的類似設定好像通常就沒必要啊啊啊啊啊啊~

好的,
像以前這樣如果你有先設定好Media Types,
那將會讓網頁執行效率有所提升,
但是問題來了....
一個網頁他奶奶的只能設定一個Media Type啊啊啊啊啊~
啊如果我是設定給Desktop裝置使用的,
那Mobile裝置用起來就會卡卡的啊~
這樣我有跑得飛快的執行效率也是沒用啊啊啊啊~(崩潰)

所以,
Media Queries天女下凡了~
讓她來拯救你!!
鋪梗鋪好久...

下一篇待續....我英文不好看文章很慢要慢慢咀嚼慢慢寫...還寫錯!!T_T

2015年4月17日 星期五

【往F2E這個路子走】Responsive Design

啊哩,這是啥玩意啊? 

簡單的說,
就是因為大家現在都可以用小小的Smart Phone開始上網看網頁,
啊為了讓大家可以在電腦和手機上都有最舒適的閱覽環境,
所以就因應而生了這種網站設計方式,
它會隨著瀏覽者所使用的螢幕大小與解析度去自動調整頁面呈現內容,
進而把你牢牢抓住不要離開我們去亂看其他沒我們漂亮的網頁這樣

啊可是我們寫程式刻網頁的人都馬知道,
馬的逼要兩種不同呈現樣貌的網頁就是要刻兩版啊!
然後如果再出個高解析度版本的又要多一版,
要PAD版本就再搞一版,
奶奶的哩,
有沒有辦法一次搞定啊?

姜姜姜~
就是透過CSS(Cascading Style Sheet)來搞定他囉!
這樣開發人員就可以只調整CSS就好囉!
不用每次都重新刻HTML檔案耶~
水啦!

但是這要怎麼做?
不要問,我剛開始學.....XD