<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    weidagang2046的專欄

    物格而后知致
    隨筆 - 8, 文章 - 409, 評(píng)論 - 101, 引用 - 0
    數(shù)據(jù)加載中……

    服務(wù)器端可控情形的Javascript跨域訪問解決方法

    2006-12-5

    ?

    我在最近的一個(gè) web 項(xiàng)目中為了實(shí)現(xiàn) bookmark 功能碰到了 javascript 跨域訪問的問題。起初,在 google 上搜的很多解決方案并不適用于我的情形,只在有一篇文章中提到的遠(yuǎn)程加載 javascript 方法從理論上看到了解決的希望。但可惜作者只是一筆帶過,并未用例子詳細(xì)說明,所以不得不摸索了一陣才把這個(gè)問題搞定。在此,希望通過本文為同樣被這個(gè)問題困擾的朋友們提供一個(gè)解決方法作為參考。如有錯(cuò)誤,歡迎指正!

    ?

    Bookmark 是目前許多 web2.0 網(wǎng)站 (http://del.icio.us/, www.diigo.com 等)都提供的熱門 feature 。它能將互聯(lián)網(wǎng)上自己喜歡的網(wǎng)頁收藏到 Bookmark 服務(wù)器上。本文要解決的問題就發(fā)生在用戶提交網(wǎng)頁 URL (還包括 Tag, Notes 等)給 Bookmark 服務(wù)器時(shí)。

    ?

    關(guān)于 URL 的提交至少可以有三種方式:

    ?

    1.?????? 登陸 Bookmark 服務(wù)器的提交頁面,將要收藏的 URL 通過該頁面提交給服務(wù)器。

    2.?????? 安裝瀏覽器插件,通過插件將 URL 提交給服務(wù)器。

    3.?????? Bookmark 服務(wù)器動(dòng)態(tài)加載 javascript 小工具到當(dāng)前頁面,通過它來完成提交工作。(參考 diigo 的例子,收藏一個(gè)網(wǎng)頁鏈接到瀏覽器收藏夾,鏈接的 URL 是一段 javascript 代碼,它會(huì)從服務(wù)器加載一段 javascript 注入當(dāng)前網(wǎng)頁)

    ?

    第一種方式開發(fā)起來最簡(jiǎn)單,但對(duì)用戶來講比較麻煩,每次都需要先登陸 Bookmark 服務(wù)器才能完成提交;第二種方式我并不熟悉插件開發(fā),而且用戶也不喜歡太多的插件堆滿自己的瀏覽器;第三種方式開發(fā)難度小,又避免了每次登陸服務(wù)器的麻煩,所以我最終采用了它。

    ?

    上面講的第三種方式中動(dòng)態(tài)加載的 javascript 小工具除了需要生成 UI 供用戶填寫信息( URL tag notes 等),當(dāng)用戶點(diǎn)擊提交的時(shí)候,還要完成與服務(wù)器通信的功能。在沒有跨域訪問經(jīng)驗(yàn)的情況下,最先想到的當(dāng)然是 ajax !但很快就會(huì)發(fā)現(xiàn)根本行不通。

    ?

    跨域訪問,簡(jiǎn)單來說就是 A 網(wǎng)站的 javascript 代碼試圖訪問 B 網(wǎng)站,包括提交內(nèi)容和獲取內(nèi)容。由于安全原因,跨域訪問是被各大瀏覽器所默認(rèn)禁止的。寫過跨域訪問 ajax 的朋友相信都遇到過被告知“沒有權(quán)限”的情況。通過 XMLHttp 來發(fā)送數(shù)據(jù)給 Bookmark 服務(wù)器的嘗試失敗了。于是,看到網(wǎng)上的一些資料,我又開始嘗試用 javascript 小工具在用戶網(wǎng)頁動(dòng)態(tài)創(chuàng)建一個(gè)隱藏的 iframe, iframe src 指向服務(wù)器的一個(gè) servlet ,試圖通過調(diào)用 iframe 中提供的 javascript 來完成與服務(wù)器的通信。但不幸的是,用戶網(wǎng)頁中的 javascript 代碼訪問 iframe 也被瀏覽器歸為跨域訪問(特指 iframe src 指向其它網(wǎng)站的情形),嘗試再次失敗。

    ?

    最終,在一篇文章中看到,與 iframe 不同,如果 A 網(wǎng)站從 B 網(wǎng)站加載 javascript A 網(wǎng)站可以自由的訪問該 javascript 的內(nèi)容,并不會(huì)被瀏覽器認(rèn)為是跨域訪問。模仿剛才 iframe 的思路,當(dāng)用戶點(diǎn)擊提交時(shí),可以動(dòng)態(tài)創(chuàng)建一個(gè) javascript 對(duì)象,該對(duì)象的 src 指向 Bookmark 服務(wù)器的一個(gè) servlet ,注意: URL Tag Notes User Password 等信息被作為 src URL 參數(shù)傳給服務(wù)器。請(qǐng)看下面的代碼:

    ?

    var url = "http://localhost:8080/Deeryard/BookmarkServlet?" +

    ?????????? "url=" + url_source + "&" + "title=" + title + "&" +

    "tag=" + tag + "&" + "notes=" + notes + "&" + "user=" + user + "&" + "password=" + password;

    ?

    url = encodeURI(url);

    ???

    //Submit to server with a trick

    var js_obj = document.createElement( "script" );

    js_obj.type = "text/javascript" ;

    js_obj.setAttribute( "src" , url);

    ???

    //Get response from server by appending it to document

    document.body.appendChild(js_obj);

    ?

    上面例子中, js_obj.setArrribute() 將信息作為 src URL 參數(shù)提交給了 Bookmark servlet 。那么用戶又如何取得服務(wù)器的響應(yīng)信息呢?答案就是最末一行代碼, servlet 的輸出必須是 javascript 代碼,它可以調(diào)用用戶網(wǎng)頁上的其他 javascript 函數(shù),以及操作 dom 對(duì)象。下面的 servlet 代碼生成了一個(gè) javascript 函數(shù)調(diào)用:

    ?

    out.write("onServerResponse(INADEQUATE_INFORMATION);");

    ?

    document.body.appendChild(js_obj) 執(zhí)行后 onServerResponse( INADEQUATE_INFORMATION) 就會(huì)得到執(zhí)行,使客戶網(wǎng)頁響應(yīng)服務(wù)器結(jié)果。這樣一個(gè)完整的通信過程就完成了。

    ?

    來總結(jié)一下這個(gè)案例,首先與很多跨域訪問的情形不同,本文提到的跨域訪問需要對(duì)服務(wù)器端進(jìn)行控制,即讓服務(wù)器端 Servlet 來適應(yīng)客戶端網(wǎng)頁 javascript 的需求;而其他一些常見的例子則對(duì)服務(wù)器端沒有控制能力,比如從其他網(wǎng)站抓內(nèi)容的小偷程序。另外,需要注意的是這種方法中實(shí)際用到了 get 方法來提交信息,從一些資料上看到, get 方法每次提交的信息不能超過 2k

    posted on 2006-12-05 22:48 weidagang2046 閱讀(9287) 評(píng)論(11)  編輯  收藏

    評(píng)論

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    IBM developerWorks上面有個(gè)文章,里面詳細(xì)講了ajax的三種數(shù)據(jù)傳輸機(jī)制,你上面這個(gè)實(shí)例就是其中的第三種方法。
    教程文章地址:
    http://www-128.ibm.com/developerworks/cn/views/xml/tutorials.jsp?cv_doc_id=110100
    需要注冊(cè)個(gè)ID才能閱讀。
    2006-12-06 09:27 | xinheqishi

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    我有個(gè)問題哦....
    比如,我第一次發(fā)送的時(shí)候創(chuàng)建一個(gè)script對(duì)象,然后在很斷的時(shí)間內(nèi)發(fā)送了第二次,也就是創(chuàng)建了第二個(gè)script對(duì)象.那天他就把第一個(gè)覆蓋了,第一個(gè)怎么辦??

    但我又不能創(chuàng)建很多個(gè)script對(duì)象,那樣很占資源,只能刪除一些對(duì)象,那樣就又可能刪除寫沒有反會(huì)的對(duì)象......

    我的前提是我則個(gè)情求比較頻繁..

    希望能解我之惑...
    email: zuan8888@gmail.com
    2007-01-13 14:37 | 剎那

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    創(chuàng)建javascript對(duì)象的時(shí)候指定id屬性可以避免覆蓋;也可以按id查找對(duì)象來判斷是否已經(jīng)返回,如果找到的話就可以看情況刪除。關(guān)于id的維護(hù)問題辦法應(yīng)該很多。比如,維護(hù)一個(gè)全局計(jì)數(shù)器。

    如果一定要同步的話(比如,第一次返回才能發(fā)第二次),建議看看javascript的wait()函數(shù)。

    ps: 我的javascript經(jīng)驗(yàn)也不多,上面的建議還需要實(shí)踐檢驗(yàn)。歡迎交流!
    2007-01-13 18:05 | weidagang2046

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    請(qǐng)問這種方式下客戶端(瀏覽器端)和Bookmark servlet端之間的關(guān)系是不是和直接通過瀏覽器訪問Bookmark servlet的關(guān)系是一樣的? 因?yàn)槲蚁胗眠@個(gè)方法來解決一個(gè)問題,A網(wǎng)站(應(yīng)該是相當(dāng)于這里的Bookmark servlet)負(fù)責(zé)控制邏輯,B網(wǎng)站負(fù)責(zé)頁面的外觀顯示.
    客戶端從B網(wǎng)站進(jìn)入之后, 要?jiǎng)討B(tài)創(chuàng)建javascript對(duì)象,提交多次請(qǐng)求, 而我想維護(hù)多個(gè)請(qǐng)求之間的狀態(tài)關(guān)系;是否和直接通過瀏覽器訪問B網(wǎng)站一樣,維持session就OK了?

    希望能解我之惑....謝謝!
    2007-01-13 19:28 | sparklet

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    因?yàn)锽ookmark Servlet對(duì)javascript一無所知,只當(dāng)成一般的網(wǎng)頁文本返回,所以我認(rèn)為和一般瀏覽器的訪問沒有區(qū)別,用session維護(hù)狀態(tài)是完全可以的。
    2007-01-13 19:39 | weidagang2046

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    可行 跨域真是雙刃劍
    2007-02-04 11:42 | 小雨

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法[未登錄]  回復(fù)  更多評(píng)論   

    可以MSN交流嗎?tangcaiyou@hotmail.com
    2007-06-17 10:45 | eric

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    我嘗試了類似的代碼卻沒有成功。
    我在一個(gè)A網(wǎng)站的portlet中,iframe了一個(gè)B網(wǎng)站的jsp頁面,當(dāng)點(diǎn)擊該jsp的某個(gè)鏈接后,我需要將一個(gè)參數(shù)傳送到A網(wǎng)站的某Servlet,可是沒有成功。
    代碼如下:
    site A的portlet:
    從IFrame中的頁面?zhèn)鱽淼膮?shù):<%=portlet_a_s%>
    <br/>
    <iframe width="300" height="300" src="http://siteB:7001/myWeb/B.jsp">
    </iframe>

    site B的jsp:
    <%@ page language="java" contentType="text/html;charset=UTF-8"%>
    <html>
    <head>
    <title>
    inner page
    </title>

    <script type="text/javascript">
    var lastScript;
    var h=document.getElementsByTagName("head")[0];

    function loadScript(url){
    var f=document.createElement("script");
    var d=new Date().getTime();
    f.type="text/javascript";
    f.id=d;
    f.src=url+'&date='+d;
    document.body.appendChild(f);
    if(lastScript&&g(lastScript))g(lastScript).parentNode.removeChild(g(lastScript));
    lastScript=d;
    }

    function g(x){
    return document.getElementById(x)
    }

    function onClickMeasureId(id){
    var hidden = g("hidden_input");
    hidden.value = id;
    var url = "http://siteA:7001/testWeb/portlets/portlet_a/PortletAServlet?id="+id;
    loadScript(url);
    }

    function onResponse(){
    alert("response");
    };
    </script>
    </head>
    <body>
    <a onclick="onClick('參數(shù)1')" href="#">參數(shù)1</a>
    </body>
    </html>

    siteA的Servlet:
    public class PorletAServlet extends HttpServlet
    {
    public void service(HttpServletRequest request,HttpServletResponse response){
    if ( request.getParameter("id") != null ){
    String id = request.getParameter("id").toString();
    HttpSession session = request.getSession();
    session.setAttribute("measure_id",request.getParameter("id") );
    try{
    response.setContentType("text/javascript");
    PrintWriter out = response.getWriter();
    out.write("onResponse();");
    }
    catch(Exception e){}
    }
    }
    }

    我執(zhí)行siteA的portal,在siteA的servlet中加入斷點(diǎn),點(diǎn)擊portlet中iframe中的鏈接,發(fā)行servlet并沒有得到執(zhí)行。實(shí)在不知道為何不成功。

    不知道博主可否提供更加完整的例子?謝謝!
    2007-06-22 14:57 | liao

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    @liao
    你的例子應(yīng)該沒有大問題,應(yīng)該調(diào)查servlet沒有得到執(zhí)行的原因。可以把url單獨(dú)拷貝出來,敲到瀏覽器的地址欄中試試看servlet能否執(zhí)行。我估計(jì)是url本身的問題,很可能沒有真正對(duì)應(yīng)到那個(gè)servlet。
    2007-06-22 16:31 | weidagang2046@gmail.com

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    你好我 我碰到了一個(gè)問題

    和你的說的類似

    希望你幫我看下

    多謝了 http://so.hr33.com/SearchResult.aspx?key=a&companyname=&zw=100&dq=100&sj=90&xl=10&jy=0&sex=2&age=0&yx=0&xz=0&hy=0&RCount=29&Page=1&type=1

    你點(diǎn)申請(qǐng)后點(diǎn)關(guān)閉就會(huì)提示 "拒絕訪問.."

    MAIL 我 colvinliu@qq.com
    2007-12-20 17:06 | colvinliu

    # re: 服務(wù)器端可控情形的Javascript跨域訪問解決方法  回復(fù)  更多評(píng)論   

    轉(zhuǎn)了一大圈 終于在這里找到了解決方法
    2010-04-22 11:21 | 唐兵

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲国产成人久久精品大牛影视| 亚洲国产精品一区二区第一页| 天天摸天天操免费播放小视频| 老司机亚洲精品影院| 女人张开腿给人桶免费视频| 国产大片免费网站不卡美女| 18禁美女黄网站色大片免费观看| 2021国内精品久久久久精免费| 国产精品1024永久免费视频| 97人妻无码一区二区精品免费| 亚洲三级在线免费观看| av无码免费一区二区三区| 91视频国产免费| 四虎免费在线观看| 免费国产综合视频在线看| 亚洲伊人久久成综合人影院| 亚洲中文字幕无码久久2017| 亚洲成人激情在线| 亚洲最大的视频网站| 亚洲乱妇老熟女爽到高潮的片 | 中国国语毛片免费观看视频| 18禁超污无遮挡无码免费网站| 无码AV片在线观看免费| 最近免费中文字幕高清大全| 九九九精品成人免费视频| 最好免费观看韩国+日本| 亚洲精品tv久久久久| 亚洲成Av人片乱码色午夜| 亚洲日韩乱码中文无码蜜桃臀| 在线综合亚洲欧洲综合网站 | 精品无码一区二区三区亚洲桃色| 亚洲人成免费网站| 久久亚洲色WWW成人欧美| 精精国产www视频在线观看免费| 色猫咪免费人成网站在线观看| 成人免费一区二区无码视频| 亚洲成?v人片天堂网无码| 亚洲av无码不卡| 亚洲精品久久久久无码AV片软件| 一级毛片试看60分钟免费播放| 99久久综合精品免费|