那為何我會遇到跨網域問題?
是這樣的,使用 PhoneGap 開發 app 時,若要跟 API server 要資料也屬於跨網域存取,不過 PhoneGap 的 webkit 設計不像我們平常在用的 browser,所以不會有此限制。只是開發過程我們會直接利用 browser debug,不會每次都把網頁放到 PhoneGap 內,然後 build、deploy 到 mobile device... 這實在太花時間了,這就是為何我需要解決 cross domain 的原因。
先來看看直接存取會發生什麼事:
這是一個基本的 AJAX request,POST 帳號密碼做登入的動作
Ext.Ajax.request({ url: 'http://api.example.com/login.php', params: { username: 'sylar', password: '123456' }, success: function(response, opts) { console.log(response.responseText); }, failure: function(response, opts) { console.log('server-side failure with status code ' + response.status); } });
於是瀏覽器 console 出現錯誤訊息:
- OPTIONS http://api.example.com/login.php?_dc=1377654028515 Origin http://localhost is not allowed by Access-Control-Allow-Origin.
- XMLHttpRequest cannot load http://api.example.com/login.php?_dc=1377654028515. Origin http://app.localhost is not allowed by Access-Control-Allow-Origin.
解法一:修改瀏覽器執行方式
這也是最快的方法Windows
chrome.exe --disable-web-security
MacOS
open -a Google\ Chrome --args --disable-web-security
解法二:Server 回應特定 header
也就是允許任何來源Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept不過會發現有個缺點,就是每次 GET / POST 時,browser 總是會先發送 OPTIONS 詢問 server,造成頻寬浪費,可以在 Ajax.request 加入下列的參數就可避免
useDefaultXhrHeader: false
Cookie 無法儲存?
由於我的 server 認證方式是使用 session,也就是登入成功後,server 會使用 set-cookie 的方式要求 browser 把 session key 存在 cookie 內,不過上述方法並無法儲存 cookie。解決的方式就是在 Ajax.request 加入參數
withCredentials: true
而 server 也必須明確指定允許的來源位址,不能用 wildcard (*),再來是 Access-Control-Allow-Credentials 值要為 true
Access-Control-Allow-Origin: http://localhost Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept Access-Control-Allow-Credentials: true
以上就是跨網域存取,server / client 要做的修改,更多關於 Sencha Touch Ajax 的用法請參考官網的 Guideline:Using AJAX - Touch 2.2.1 - Sencha Docs
參考資料
javascript - Ext.Ajax.request sending OPTIONS request cross-domain when jQuery.ajax sends GET - Stack Overflow
ajax - Cookies not saved in Sencha Touch 2 - Stack Overflow
沒有留言:
張貼留言