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

星期五, 12月 02, 2016

Break Same-origin policy by Nginx

HTML 5 愈來愈成熟,可預見的未來不再容許 ActiveX 的存在,替代方案是 WebSocket 或類似的架構,說穿了就是把一些髒事有安全疑慮的工作交給本機的一個輕量化 Web Server 處理。

不過「同源政策」又出來搗亂了,因為網頁所在伺服器與瀏覽器本來就不該一樣,而我能拿到的一個 ActiveX 替代方案參考實作,又偏偏不開放 Access-Control-Allow-Origin 這個表頭(一定是故意!),沒關係,請 Nginx 來助陣,設定如下:


如此一來,原先在 JavaScript 存取 http://localhost:61161 受到同源政策拘束的問題,改往 http://localhost:6116 即可解決。

星期二, 7月 12, 2016

Simplest AJAX client / server with CORS

先談最簡單的 AJAX server:
  • NodeJS
  • Module: Express (optional)
  • 網路上一大堆 http.createServer(req, res) 範例
  • 防火牆設定
接著在 server 上準備一個 jQuery based 網頁去呼叫上述的服務,但因為網頁並沒有真的部署在任何 Web Server 上,所以在瀏覽器開啟的網址列會是以 file:// 開頭,一般受限於 CORS 會不能對 server 發起 Request,或精確地說,在瀏覽器預檢 preflight 失敗後就放棄,若開啟任何開發者工具之類的側錄看來像沒反應。針對各種瀏覽器的解決如下:
  • Chrome、Firefox、Safari:在 server js 加這一行
    • response.setHeader("Access-Control-Allow-Origin", "*");
  • IE:在網頁傳送 ajax 之前加這一行
    • $.support.cors = true;
  • Edge:以系統管理員身分開啟命令列提示,輸入
    • CheckNetIsolation LoopbackExempt -a -n=Microsoft.MicrosoftEdge_8wekyb3d8bbwe
這絕對是我看過最怪的解法了,不過有憑有據,也真的有效。

星期四, 7月 11, 2013

不是 Cross-origin resource sharing 難,而是⋯⋯

整理幾個最近遭遇的問題:
  1. Microsoft IE 11.0.9431.0 在 localhost 但 port 不同的情況下,認為這不算跨域,沒作預檢(preflight),直接發送真正需要的 Request。
  2. Google Chrome 28.0.1500.71 即使預檢失敗,仍會發送真正需要的 Request。
  3. Microsoft IIS 8 即使未設 Access-Control-Allow-Methods,仍接受 GET、OPTIONS。
  4. System.Web.Http.ApiController 的子類別最好多寫一個空的方法「public void Options() { }」,否則 Firefox 預檢失敗,就不發送真正需要的 Request 了,雖然這是最標準的,但讓我誤會了好幾個小時,以為怎麼 IE 10、Chrome 都正常,唯獨 Firefox 不行?

星期三, 7月 10, 2013

從瀏覽器呼叫 Restful Web API 的要訣

前文所提,瀏覽器要支援 Cross-origin resource sharing,Firefox 或 Chrome 都沒問題,IE 只有 10 或更新的版本才有機會,而且要看文件模式(Document Mode)是不是「標準」或「相容」(Quirks),若其他像是 Internet Explorer 9 standards、Internet Explorer 8 standards 等都不行。
問題來了,若使用者雖然是 IE 10,但他調成不支援的文件模式,要如何交待?這時必須先用 JavaScript 偵測,並在不符條件的情況下提示。但用 navigator.userAgent 是無效的,因為它只對瀏覽模式(Browser Mode)有反應,對文件模式一無所知。幸好 IE 還有個特別的屬性叫 document.documentMode,如果小於 10 再提示就對了。
網路上也有人提到,即使是 IE 8 或 IE 9,還是有機會支援,只是限制一大堆。但連 jQuery 都明確表態不會採納了,我這種小角色又何必為難自己?

星期五, 7月 05, 2013

Restful Web API 服務與測試分離

過去我的 Restful Web API 在跨域限制下為了方便,都把服務本身與測試服務的網頁放在同一個網站,但這讓人蠻不舒服的。想要把它們分開,網路上大致流傳著兩種解法:JSONP 與 Cross-origin resource sharing,研究之後發現,前者其實改變了服務的介面,不敢領教,所以決定用後者。有幾個要點(假設服務在 http://localhost/myService,測試首頁在 http://localhost:12345/test.html):
  • 服務端要設定對測試來源開放,以 IIS 7 為例,在 Web.config configuration -> system.webServer -> httpProtocol -> customHeaders 需要以下的節點:<add name="Access-Control-Allow-Origin" value="http://localhost:12345" />
  • 測試端我用的是 jQuery 發送 Ajax,它當然也要知道服務在哪提供,像這樣:$.ajax({url: "http://localhost/myService", success: ..., error: ...});
  • 測試端使用的瀏覽器會挑,像 IE 10 以前都不行,但 Firefox、Chrome 就沒這問題,可能要注意一下。
  • 若在 Visual Studio 同一 Solution,StartUp Project 設在測試專案,Start Page 設在測試首頁,服務專案的 Properties -> Web -> Start Actions 設在「Don't open a page. Wait for a request from an external application.」,這樣才會同時載入兩個網站。