YUI3 PR1試用 - Cross Domain Request

 Sat, 08 Nov 2008 23:59:45 +0800

YUI3的IO模組除了有XMLHttpRequest的功能外,還可以利用模組裡面的io.swf來做出cross domain request,突破XMLHttpRequest無法跨domain的限制。

其實flash的cross domain request還是有限制的,就是伺服器上必須有一個crossdomain.xml,描述可以接受request的domain。像這樣:

<?xml version="1.0"?>
<cross-domain-policy>
  <allow-access-from domain="a.b.c" />
  <allow-access-from domain="d.e.f" />
</cross-domain-policy>

這樣就可以接受a.b.c與d.e.f網站送出的request。如果要讓所有網站都可以對伺服器發出request,就:

<?xml version="1.0"?>
<cross-domain-policy>
  <allow-access-from domain="*" />
</cross-domain-policy>

接下來寫一個簡單的網頁,擷取blog上面的rss,然後秀出title list(還是用YUI3網站上的tutorial改的):

<html>
<script src="build/yui/yui-min.js"></script>
<body>
<input type="button" value="test" id="test">
<div id="panel"></div>
<script>
YUI().use('io', function(Y) {
    var xdrConfig = {
        id: 'flash',
        yid: Y.id,
        src: 'build/io/io.swf'
    };
    Y.io.transport(xdrConfig);
    var cfg = {
        method: 'GET',
        xdr: {
            use: 'flash',
            responseXML: true
        },
        on: {
            success: function(id, o, a) {
                Y.get('#panel').set('innerHTML','');
                try {
                    var parser = new DOMParser();
                    var xmldoc = parser.parseFromString(o.responseText, 'text/xml').documentElement;
                }catch(e){
                    try {
                        var xmldoc=new ActiveXObject("Microsoft.XMLDOM");
                        xmldoc.async="false";
                        xmldoc.loadXML(o.responseText);    
                    }catch(e){alert(e);}
                }
                var objs = xmldoc.getElementsByTagName('title');
                var str = "";
                str += "<ul>";
                for (var i=0; i<objs.length; i++) {
                    str += "<li>" + objs[i].firstChild.nodeValue + "</li>";
                }
                str += "</ul>";
                Y.get('#panel').set('innerHTML', str);
            },
            failure: function(id, o, a) {
                Y.get('#panel').set('innerHTML','Failed...');
            },
            start: function(id, a) {
                Y.get('#panel').set('innerHTML', 'Starting...');
            },
            abort: function(id, a) {
                Y.get('#panel').set('innerHTML','Aborted...');
            }
        }
    };
    Y.on('io:xdrReady', function() {
        Y.get('#test').on('click', function(e) {
            var obj = Y.io(
                "http://blog.fillano.idv.tw/rss.php?blogId=1&profile=rss20",
                cfg
            );
        });
    });
});
</script>
</body>
</html>

比較麻煩的是,xdr只能回傳responseText,所以必須想辦法把responseText解析成DOM物件,這樣程式才容易處理,在IE需要用到Microsoft.XMLDOM這個activeX物件,在firefox/mozilla則可利用DOMParser物件。(不過這幾個方法可能不適用於其他瀏覽器...究竟不是標準方法)

io模組的使用比較不那麼直覺,首先要用Y.io.transport(xdrconfig)來設定xdr的一些基本參數。使用時,先組好一個request config物件,然後傳給Y.io(config),這時request就會發動,而事件處理函數也會照指定的發動。

下面的連結是自己寫的例子,內容跟上面的程式碼一樣:
http://www.fillano.idv.tw/test344.html