1. 程式人生 > >通用版父頁面跨域訪問iframe裡面的內容解決方案,jupyter+tornado跨域通訊解決方案

通用版父頁面跨域訪問iframe裡面的內容解決方案,jupyter+tornado跨域通訊解決方案

1、問題:獲取jupyter裡面的內容

現在已經將jupyter放進iframe裡面,現在的問題描述為:在父頁面獲取iframe裡面的內容,iframe裡面就是jupyter,這裡的父頁面是自己搭建的tornado伺服器開啟的頁面,網址為127.0.0.1:9000iframe裡面的jupyter用的網址是127.0.0.1:8888,所以涉及到了跨域請求。

1.1、通用版解決跨域問題(通用的不限於tornado),可以用於其他任何場景

父頁面獲取iframe裡面內容的解決方案如下:

實驗如下:開兩個tornado伺服器,一個埠9000,一個埠9001

現在在9000頁面要放一個iframe指向9001的一個頁面,再在9000父頁面列印9001iframe

裡面的東西是訪問不了的,提示跨域了,埠不一樣


目標父頁面127.0.0.1:9000訪問自己iframe src=127.0.0.1:9001裡面的內容

解決這個問題的方案的思路:

1、在127.0.0.1:9000頁面使用js程式碼動態增加一個iframesrc是與127.0.0.1:9001同級目錄下的一個頁面127.0.0.1:9001/execB.html

2、然後先去9001建立好這個頁面execB.html配置好url,保證能訪問到。

3、在127.0.0.1:9001/execB.html中,去做想做的js操作(如呼叫127.0.0.1:9001中的一個js函式,或者改變背景色等都在這個頁面進行)

原理解釋:9000頁面現在有兩個iframe,一個訪問9001,一個是動態增加的訪問9001/execB.html,9000載入完後返回9001的<body><html>….</html></body>標籤,此時,9001/execB.html也返回了,但是9001/execB.html裡面有操作9001的DOM的js程式碼如:parent.window.frames[“myframe9000”].document.getElementById(“test”).innerHTML,這樣就相當於9001/execB.html再操作9001裡面的DOM,就能夠操作成功

具體程式碼如下:

127.0.0.1:9000

html程式碼


js程式碼:

window.onload=function (ev) {
    function exec_iframe(){
    if(typeof(exec_obj)=='undefined'){
        exec_obj = document.createElement('iframe');
        exec_obj.name = 'tmp_frame';
        exec_obj.src = 'http://127.0.0.1:9001/execB';
        exec_obj.style.display = 'none';
        document.body.appendChild(exec_obj);//動態建立一個iframe
    }else{
        exec_obj.src = 'http://127.0.0.1:9001/execB?' + Math.random();
    }
  }

  exec_iframe()
}

127.0.0.1 :9001

html程式碼(目標id=notebook裡面的內容被獲取,被顯示,顏色更改):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
test9001
<div id="notebook">
    <p>這個頁面放到iframe裡面,目標獲取這裡的內容就算成功</p>
</div>
</body>
</html>

127.0.0.1:9001/execB.html(真正做取值的js頁面,被動態新增到9000頁面iframe)

js程式碼(去操作同一個域名下的127.0.0.1:9001的內容獲取id=notebook裡面的內容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
</html>
<script src="http://lib.baomitu.com/jquery/3.3.1/jquery.js"></script>
<script>
   //jquery操作方式,變個顏色
   // $('#notebook', window.parent.myframe.document).css("backgroundColor","red")

   //js的操作方式,變個顏色
   parent.window.frames["myframe"].document.getElementById("notebook").style.backgroundColor = "green";

   var temp = parent.window.frames["myframe"].document.getElementById("notebook").innerHRML;//取值
   console.log(temp)
</script>

至此,跨域訪問成功~

2、目標:自己的tornado伺服器的一個父頁面(127.0.0.1:9000/test)要取得iframe裡面(127.0.0.1:8888/notebooks/test2.ipynb)的jupyter伺服器的值。

發現其實jupyter自身還有一層保護,通過閱讀文件發現,還要去設定jupyter被引用的域名是誰。


(同時可以閱讀原始碼:notebook/base/handlers.py 62行開始定義了content_security_policy函式的操作,有相同描述,下文有解釋。)

如果不新增上面的這串程式碼,在自己寫的父頁面裡寫

<iframe id="myframe" name="myframe" src="http://127.0.0.1:8888/notebooks/test2.ipynb" frameborder="1" style="" height="400" width=“720"></iframe>

將會導致下圖1這裡都打不開,將會顯示圖2這種東西,就是self指向是不對的,不允許其他的頁面的iframe指向自己


1


2

那麼添加了下面這串之後一切顯示正常。但是現在的需求是獲取iframe的值,然後好在tornado服務端存入資料庫,好跟蹤記錄學生的學習情況。


使用1種所說的解決跨域的方案。在jupyter目錄下建立execB.html,讓這個execB.html去操作jupyter裡面的DOM獲取裡面的元素。本來是可以實現的。結果jupyter內部的content_security_policy定義的策略,讓execB.html也成了允許範圍之外的人

notebook/base/handlers.py裡面說的很清楚,如下圖:


就是說,如果settings定義了headers就用它的,那我們現在是定義了的(就是上面讓定義的在這裡:~.jupyter/jupyter_notebook_config.py,如過不定義自己的tornado伺服器的頁面裡的iframe顯示不了,但是這裡必須顯示出來,不然沒意義)但是現在定義了,因為execB.html也是一個動態建立的iframe,它又顯示不了。現在這種跨域取值的方式因為jupyter自身安全保護的機制取不了值。只有換一種思路~~~~

3、jupyter取值通過ajax jsonp跨域將資料傳給tornado伺服器

我現在想在jupyter(隨意開啟一個jupyter notebook http://127.0.0.1:8888/notebooks/test2.ipynb)中獲取了值(學生通過jupyter列印的返回結果)之後,通過更改jupyter原始碼,在原始碼中新增ajax方式,在jupyter中將獲取的結果傳給我自己的tornado服務端,然後就可以美滋滋的將學生操作的結果值存資料庫了。

需求:將jupyter notebook中列印的結果傳到自己的tornado服務端,在tornado服務端寫sql語句將jupyter notebook前端頁面傳遞過來的資料儲存,方便顯示到其他地方(二次開發jupyter notebook,將其結果作為一種使用jupyter的學生的操作反饋顯示在網站後臺)

3.1、jupyter頁面採用修改原始碼的方式

在jupyter原始碼根目錄下找到notebook/templates/notebook.html新增如下程式碼
window.onload=function () {
    //var temp_result = $("#notebook  div[class ~='selected'] .output_wrapper .output .output_text pre").text())
   var temp_result = $("#notebook .output_wrapper .output .output_text pre").text()
   console.log(temp_result)
}

3.2、新增ajax程式碼使用jsonp的方式做跨域請求

notebook/templates/notebook.html中新增ajax請求的程式碼

<script>
window.onload=function () {
    //temp.push($("#notebook  div[class ~='selected'] .output_wrapper .output .output_text pre").text())
   var temp_result = $("#notebook .output_wrapper .output .output_text pre").text()
   //console.log(temp_result)
    
   $.ajax({
       url: 'http://127.0.0.1:9000/ajaxjupyter',//http://127.0.0.1:9000/ajaxjupyter?callbackfun=jsonpCallback&temp_result=temp_result
       type: 'get',
       dataType: 'jsonp',
       jsonp:"callbackfun",//傳遞給請求處理程式或頁面的,用以獲得jsonp回撥函式名的引數名(預設為:callback)
       jsonpCallback:"jsonpCallback",//自定義的jsonp回撥函式名稱,預設為jQuery自動生成的隨機函式名,如果定義了就success:function(){}就失效
       data: {
           temp_result:temp_result
       },
   });
}
 function jsonpCallback(data) {
           console.log(data)
       }
</script>

3.3、tornado服務端需要做接收和處理返回

class AjaxjupyterHandler(HomeHandler):
    def get(self):
        temp_result = self.get_argument("temp_result", "")
        callbackfun = self.get_argument("callbackfun", "") #接受callback的名字callbackfun=jsonpCallback

        res = dict()
        res["status"] = 0
        res["info"] = "新增成功"
        res["temp_result"] = temp_result

        self.set_header("content-type", "application/json")
        data = json.dumps(res)

相關推薦

通用頁面訪問iframe裡面內容解決方案jupyter+tornado通訊解決方案

1、問題:獲取jupyter裡面的內容現在已經將jupyter放進iframe裡面,現在的問題描述為:在父頁面獲取iframe裡面的內容,iframe裡面就是jupyter,這裡的父頁面是自己搭建的tornado伺服器開啟的頁面,網址為127.0.0.1:9000,ifram

iframe頁面頁面元素的訪問以及js變量的訪問

++ src 行修改 動態 class ria 方法 修改 左右 1、子頁面訪問父頁面元素 parent.document.getElementById(‘id‘)和document相關的方法都可以這樣用 2、父頁面訪問子頁面元素 document.

WebBrowser瀏覽器訪問iframe

1 使用幫助類訪問iframe public class CloseJsWindow { [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]

頁面內獲取獲取iframe內的變數或者是獲取iframe內的值

前提:頁面不可跨域訪問,必須同一域名下,否則返回值為空 父頁面 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="view

子窗口訪問頁面iframe中的iframetop打開的子窗口訪問頁面中的iframe中的iframe

frame 技術分享 收藏 主頁 art cond pos shu log 子窗口訪問父頁面iframe中的iframe 子窗口訪問最頂層頁面中的iframe中的iframe top打開的子窗口訪問父頁面中的iframe中的iframe top打開的子窗口訪問最頂層頁面中的

iframe 訪問session/cookie丟失問題解決方法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Asp.net MVC訪問頁中巢狀的iframe頁面如果session或cookie過期登入驗證超時怎樣自動跳轉到登入頁

一般登入驗證的過濾器中,使用驗證過濾器的Redirect方法,將請求重定向到指定的URL。但是如果我們要訪問的頁面是一個巢狀在母版頁中的iframe頁面時,這種重定向只會對iframe頁面湊效,也就是會將iframe也重定向到登入頁,這樣就有違我們的目的了。所以我就嘗試了很多方法來實現讓整個頁面重定向到登入頁

A系統訪問其他系統頁面

由於專案是對老系統進行技術升級改造,需要很長一段時間才會改造完畢,在改造過程為了不影響客戶使用,所以決定在新系統不斷改造的過程中,依然可以訪問老系統,就是將老系統的頁面巢狀見新系統,在巢狀的過程中遇到如下問題:當新系統拿著使用者資訊登陸進老系統,老系統的頁面成功巢狀進新系統,

JS訪問操作iframe

很多人一直都有個想法,要是可以隨心所欲的操作iframe就好了。這樣靜態頁面也就有了相當於後臺動態頁面php,jsp,asp中include,require實現統一多頁面佈局的能力。 通過Javascript的幫忙我們可以像後臺一樣動態載入操作iframe物件屬性src指向

訪問頁面

    如果是同域中的網頁,可以直接用ajax等方式直接訪問,但是如果訪問的是外部網站內容,則屬於跨域。     這樣就會報關於Access-Control-Allow-Origin的錯。這個時候是因為資料返回的時候http的協議頭缺少Access-Control-Allo

解決jquery ajax在訪問post請求的時候ie9以下無效(包括ie9)的問題

jquery src actor div tick 屬性 dex 啟用 logs 最近在做項目的時候遇到一個問題,就是跨域請求ajax的時候ie9以下的瀏覽器不可以訪問,直接執行error裏面的代碼,但是也不報錯,就上網查了查,發現了一個很好用的方法,在這裏記錄一下,也希望

ASP.NET MVC & WebApi 中實現Cors來讓Ajax可以訪問 (轉載)

詳細 簡介 part bsp bob 打印 不能 res user 什麽是Cors? CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。它允許瀏覽器向跨源服務器,發出XMLHttpRequest請求,從而克服了

第二百七十四節同源策略和訪問

ron 使用 outlook 是否 secure .com 相對 100% wid 同源策略和跨域訪問 什麽是同源策略 盡管瀏覽器的安全措施多種多樣,但是要想黑掉一個Web應用,只要在瀏覽器的多種安全措施中找到某種措施的一個漏洞或者繞過一種安全措施的方法即可。瀏覽器

JQuery+ajax+jsonp 訪問

url .text java jquery rip getjson round show ajax <html> <head> <meta http-equiv="Content-Type" content="text/html; c

iframe 調用頁面元素

default 定義 fault document .get dtd parent server scrip <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="IFrame.aspx.cs" Inher

兩個java項目,訪問時,瀏覽器不能正確解析數據問題

back false callback require autowire data category 解析 als @Controller@RequestMapping(value = "api")public class ApiItemCatController { @

訪問之CORS

基本 支持 oar 技術分享 過程 ets attribute 響應 api CORS:定義 2014年1月16日,W3C的Web應用工作組(Web Applications Working Group)和Web應用安全工作組(Web AppSec)聯合發布了跨源資

解決微信瀏覽器訪問手機頁面:您訪問頁面無手機頁面是否進一步訪問電腦

hash asc meta 微信瀏覽器 not ont 也會 clas split dz論壇總是報502沒辦法了,發到這裏備份。 這個問題困擾樓主很長時間了,具體原因因為不懂php沒去研究源碼,所以只能用js解決了。也就是大家常見的通過修改source\language\l

iframe交互(一)頁面自動高度

name this vsp 父頁面 scroll 是否 lin () bsp //父頁面源碼 <body style="border:1px solid red;width:200px;height:500px;" onload="IFrameResize()"

轉 easyUI的iframe頁面操作頁面元素

itl 代碼 iframe yui com con 按鈕 頁面 tabs 曾經試過這樣的方法 在iframe子頁面獲取父頁面元素 代碼如下: $(‘#objId‘, parent.document); 這樣可以獲得父頁面的元素,但是