search
HomeWeb Front-endH5 TutorialHTML5编程之旅-Communication技术初探

   本文主要探讨用于构建实时跨源通信的两个模块:跨文档消息通信(Cross Document Messaging)和XMLHttpRequestLevel2。通过这两个模块,我们可以构建不同域间进行安全通信的Web应用。 

一、跨文档消息通信

       出于安全方面的看的考虑,运行在同一浏览器中的框架标签页、窗口间的通信一直多受到严格的限制。但是现实中还存在一些合理的让不同站点的内容能在浏览器内进行交互的需求,其中Mashup就是一个典型的例子,它是各种不同应用的结合体。为了满足上述需求,引入了一种新的功能:跨文档消息通信。其可以确保iframe、标签页、窗口间安全地进行跨源通信。

  发送消息使用postMessage API,其示例代码如下:

chatFrame.contentWindow.postMessage(content,url);

  接受消息时,需要在页面中添加一个事件处理函数,当消息到达时,通过检查消息的来源来决定如何对这条消息如何处理,示例代码如下:

window.addEventListener("message",messageHandler,true);
    function messageHandler(e){
        switch(e.origin){//表示数据发送源
        case "friend.example.com":
            //处理消息
            processMessage(e.data);//发送方实际传送的消息
            break;
        default:
            //其他消息来源
            //消息被忽略。
    }
}

  postMessage API提供了一种交互方式,使得不同源的iframe之间可以进行消息通信。

  HTML5 通过引入源的感念对域安全进行了阐明和改进。源是网络上用来建立信任关系的地址的子集。源由规则(scheme)、主机(host)、端口(port)组成,例如由于scheme(https、http)不同,则源不同。

    跨源通信通过 源来确定发送者,这就使得接收方可以忽略或者拒绝来自不可信源的消息。同时需要通过添加监听事件来接受消息,以避免被不可信应用程序的信息所干扰。但是在使用外来消息时,即便是可靠的数据源,也同样要谨慎,以防止内容注入。

    在使用postMessage API时,需要遵循以下步骤:

    1、检查浏览器是否支持

if(typeof window.postMessage === undefined){
//浏览器不支持postMessage
}

    2、发送消息

window.postMessage("Hello","xx.example.com");

第一个参数包含要发送的数据,第二个参数时消息传递的目的地。

如果要发送消息给iframe,则使用如下代码:

document.getElementById("iframe")[0].contentWindow.postMessage("Hello","xx.example.com");

    3、监听消息事件

window.addEventListener("message",messageHandler,true);
var originWhiteList = ["a.example.com","b.example.com","c.example.com"];
function messageHandler(e){
    if(checkWhiteList(e.origin)){
        processMessage(e.data);//发送方实际传送的消息
    }else{
        //忽略发送的消息
    }
}
 
function checkWhiteList(origin){
    for(var i = 0; i<originWhiteList.length; i++){
        if(origin === originWhiteList[i]){
            return true;
        }
    }
    return false;
}

 二、XMLHttpRequestLevel2 

  XMLHttpRequestLevel2是XMLHttpRequest的改进版本,主要涉及:跨源XMLHttpRequess和进度事件(Progress events)。

  XMLHttpRequest仅限于同源通信,XMLHttpRequestLevel2通过跨资源共享实现(Cross Origin Resource Sharing)跨源XMLHttpRequests。

  在XMLHttpRequest中通过readystatechange事件来响应进度,但是其在某些浏览器中不被兼容。XMLHttpRequestLevel2用了一个有意义的名字Progress进度来命名进度事件。其进度事件的名称主要有loadstart、progress、abort、error、load、loadend。通过对程序属性设置回调函数,可以实现对这些事件的监听。

  在使用XMLHttpRequestLevel2时,需要遵循以下步骤:

    1、检查浏览器是否支持

var xhr = new XMLHttpRequest();
if(typeof xhr.withXredentials === undefined){
    //浏览器不支持XMLHttpRequest
}

    2、构建跨源请求

var crossOriginRequest = new XMLHttpRequest();
crossOriginRequest.open("GET","http://www.example.com",true);

  在请求过程中,务必确保能够监听到错误,以找出出错原因,解决问题。

    3、使用进度事件

crossOriginRequest.onprogress = function(e){
    var total = e.total;
    var loaded = e.loaded;
    if(e.lengthComputable){
        //处理其他事情
    }
}
 
crossOriginRequest.upload..onprogress = function(e){
    var total = e.total;
    var loaded = e.loaded;
    if(e.lengthComputable){
        //处理其他事情
    }
}

三、postMessage API示例应用

以跨源聊天应用为例,来演示门户页面和聊天部件之间的交互。

    1、创建postMessagePortal.html页面

<!DOCTYPE html>    
    <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>跨源通信-WebChat</title>
    <link rel="stylesheet" href="styles.css">
    </head>
     
    <h1>跨源通信门户</h1>
    <p><b>源</b>: http://portal.example.com:8080</p>
    状态 <input type="text" id="statusText" value="Online">
    <button id="sendButton">更改状态</button>
    <p>
    使用postMessage发送一个状态,以更新包含在此页面中的widgetiframe。
    </p>
    <iframe id="widget" src="http://chat.example.net:8080/communication/postMessageWidget.html"></iframe>
    <script>
        var targetOrigin = "http://chat.example.net:8080";
        var notificationTimer = null;
        function messageHandler(e){
            if(e.origin == targetOrigin){
                notify(e.data);
            }else{
                //忽略
            }
        }
        
        function sendString(s){
            document.getElementById("widget").contentWindow.postMessage(s,targetOrigin);
        }
        function notify(message){
            alert(message);
        }
        function sendStatus(){
            var statusText = document.getElementById("statusText").value;
            sendString(statusText);
        }
        function loadDemo(){
            document.getElementById("sendButton").addEventListener("click",sendStatus,true);
            sendStatus();
        }
        window.addEventListener("load",loadDemo,true);
        window.addEventListener("message",messageHandler,true);
    </script>

2、创建postMessageWidget.html

<!DOCTYPE html>
    <head>
       <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>widget</title>
    <link rel="stylesheet" href="styles.css">
    </head>
    <h1>Widget iframe</h1>
    <p><b>源</b>: http://chat.example.net:8080</p>
    <p>通过门户设置状态为: <strong id="status"></strong> <p>
     
    <p>
        <input type="text" id="messageText" value="Widget notification.">
        <button id="actionButton">发送通知</button>
    </p>
     
    <script>
        var targetOrigin = "http://portal.example.com:8080";
        window.addEventListener("load",loadDemo,true);
        window.addEventListener("message",messageHandler,true);
         
        function loadDemo(){
            document.getElementById("actionButton").addEventListener("click",
            function() {
                var messageText = document.getElementById("messageText").value;
                sendString(messageText);
            }, true);
        }
         
        function messageHandler(e) {
            if (e.origin === "http://portal.example.com:8080") {
                document.getElementById("status").textContent = e.data;
            } else {
                // ignore messages from other origins
            }
        }
         
        function sendString(s) {
            window.top.postMessage(s, targetOrigin);
        }
    </script>

  注意:第一、上述的两个页面需要部署到web服务器;第二、两个页面必须来自不同的域。如果要在本机部署,则需要更改hosts文件,增加:

127.0.0.1 portal.example.com
127.0.0.1 chat.example.net

  修改完成后,需要关闭浏览器,再次重新打开。

四、XMLHttpRequestLevel2示例应用

  1、创建crossOriginUpload.html页面:

<!DOCTYPE html>
<head>
header(“Access-Control-Allow-Origin: *”); 
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>上传地理数据</title>
<link rel="stylesheet" href="styles.css">
</head>
<script>
 
    function loadDemo() {
        var dataElement = document.getElementById("geodata");
        dataElement.textContent = JSON.stringify(geoData).replace(",", ", ", "g");
     
        var xhr = new XMLHttpRequest()
        if (typeof xhr.withCredentials === undefined) {
            document.getElementById("support").innerHTML = "浏览器不支持跨源XMLHttpRequest";
        } else {
            document.getElementById("support").innerHTML = "浏览器支持跨源XMLHttpRequest";
        }
     
        var targetLocation = "http://geodata.example.net:8080/upload";
     
        function setProgress(s) {
            document.getElementById("progress").innerHTML = s;
        }
     
        document.getElementById("sendButton").addEventListener("click",
            function() {
                xhr.upload.onprogress = function(e) {
                    var ratio = e.loaded / e.total;
                    setProgress("已上传" + ratio + "%");
                }
    xhr.onprogress = function(e) {
    var ratio = e.loaded / e.total;
    setProgress("已下载" + ratio + "%");
    }
     
                xhr.onload = function(e) {
                    setProgress("完成");
                }
     
                xhr.onerror = function(e) {
                    setProgress("错误");
                }
     
                xhr.open("POST", targetLocation, true);
                geoDataString = dataElement.textContent;
                xhr.send(geoDataString);
            }, true);
     
    }
    window.addEventListener("load", loadDemo, true);
 
</script>
 
<h1>XMLHttpRequest Level 2</h1>
<p id="support"></p>
 
<h4>上传地理数据:</h4>
<textarea id="geodata">
</textarea>
</p>
 
<button id="sendButton">上传</button>
 
<script>
geoData = [[39.080018000000003, 
39.112557000000002, 
39.135261, 
39.150458, 
39.170653000000001, 
39.190128000000001, 
39.204510999999997, 
39.226759000000001, 
39.238483000000002, 
39.228154000000004, 
39.249400000000001, 
39.249533, 
39.225276999999998, 
39.191253000000003, 
39.167993000000003, 
39.145685999999998, 
39.121620999999998, 
39.095761000000003, 
39.080593, 
39.053131999999998, 
39.02619, 
39.002929000000002, 
38.982886000000001, 
38.954034999999998, 
38.944926000000002, 
38.919960000000003, 
38.925261999999996, 
38.934922999999998, 
38.949373000000001, 
38.950133999999998, 
38.952649000000001, 
38.969692000000002, 
38.988512999999998, 
39.010652, 
39.033088999999997, 
39.053493000000003, 
39.072752999999999], 
[-120.15724399999999, 
-120.15818299999999, 
-120.15600400000001, 
-120.14564599999999, 
-120.141285, 
-120.10889900000001, 
-120.09528500000002, 
-120.077596, 
-120.045428,
 -120.0119, 
 -119.98897100000002, 
 -119.95124099999998, 
 -119.93270099999998, 
 -119.927131, 
 -119.92685999999999, 
 -119.92636200000001, 
 -119.92844600000001, 
 -119.911036, 
 -119.942834, 
 -119.94413000000002, 
 -119.94555200000001, 
 -119.95411000000001, 
 -119.941327, 
 -119.94605900000001, 
 -119.97527599999999, 
 -119.99445, 
 -120.028998, 
 -120.066335, 
 -120.07867300000001, 
 -120.089985, 
 -120.112227, 
 -120.09790700000001, 
 -120.10881000000001, 
 -120.116692, 
 -120.117847, 
 -120.11727899999998,
  -120.14398199999999]
  ];
</script>
 
<p>
    <b>状态: </b> <span id="progress">准备</span>
</p>

  注意:部署web应用,运行crossOriginUpload.html页面时,可能会才出现如下的提示错误:

 

  这是因为访问一页面的域与所请求的域非同源造成的。且浏览器是根据响应头的规则来确定这个域是否同源可以接收。

  因此我们需要geodata.example.net:8080/upload在返回内容时,设置Header Access-Control-Allow-Origin,即:

  Response.AddHeader("Access-Control-Allow-Origin","*") ;

  浏览器在接收到服务器返回信息时,会检查响应头的Access-Control-Allow-Origin,它的值标识请求内容所允许的域。如果将服务器设置Access-Control-Allow-Origin为*,表明该返回信息允许所有源访问。如果设置为具体的域,如xx.com,就表明除了同源外,只允许域来自xx.com的访问。

 以上就是HTML5编程之旅-Communication技术初探的内容,更多相关内容请关注PHP中文网(www.php.cn)!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
H5 Code Examples: Practical Applications and TutorialsH5 Code Examples: Practical Applications and TutorialsApr 25, 2025 am 12:10 AM

H5 provides a variety of new features and functions, greatly enhancing the capabilities of front-end development. 1. Multimedia support: embed media through and elements, no plug-ins are required. 2. Canvas: Use elements to dynamically render 2D graphics and animations. 3. Local storage: implement persistent data storage through localStorage and sessionStorage to improve user experience.

The Connection Between H5 and HTML5: Similarities and DifferencesThe Connection Between H5 and HTML5: Similarities and DifferencesApr 24, 2025 am 12:01 AM

H5 and HTML5 are different concepts: HTML5 is a version of HTML, containing new elements and APIs; H5 is a mobile application development framework based on HTML5. HTML5 parses and renders code through the browser, while H5 applications need to run containers and interact with native code through JavaScript.

The Building Blocks of H5 Code: Key Elements and Their PurposeThe Building Blocks of H5 Code: Key Elements and Their PurposeApr 23, 2025 am 12:09 AM

Key elements of HTML5 include,,,,,, etc., which are used to build modern web pages. 1. Define the head content, 2. Used to navigate the link, 3. Represent the content of independent articles, 4. Organize the page content, 5. Display the sidebar content, 6. Define the footer, these elements enhance the structure and functionality of the web page.

HTML5 and H5: Understanding the Common UsageHTML5 and H5: Understanding the Common UsageApr 22, 2025 am 12:01 AM

There is no difference between HTML5 and H5, which is the abbreviation of HTML5. 1.HTML5 is the fifth version of HTML, which enhances the multimedia and interactive functions of web pages. 2.H5 is often used to refer to HTML5-based mobile web pages or applications, and is suitable for various mobile devices.

HTML5: The Building Blocks of the Modern Web (H5)HTML5: The Building Blocks of the Modern Web (H5)Apr 21, 2025 am 12:05 AM

HTML5 is the latest version of the Hypertext Markup Language, standardized by W3C. HTML5 introduces new semantic tags, multimedia support and form enhancements, improving web structure, user experience and SEO effects. HTML5 introduces new semantic tags, such as, ,, etc., to make the web page structure clearer and the SEO effect better. HTML5 supports multimedia elements and no third-party plug-ins are required, improving user experience and loading speed. HTML5 enhances form functions and introduces new input types such as, etc., which improves user experience and form verification efficiency.

H5 Code: Writing Clean and Efficient HTML5H5 Code: Writing Clean and Efficient HTML5Apr 20, 2025 am 12:06 AM

How to write clean and efficient HTML5 code? The answer is to avoid common mistakes by semanticizing tags, structured code, performance optimization and avoiding common mistakes. 1. Use semantic tags such as, etc. to improve code readability and SEO effect. 2. Keep the code structured and readable, using appropriate indentation and comments. 3. Optimize performance by reducing unnecessary tags, using CDN and compressing code. 4. Avoid common mistakes, such as the tag not closed, and ensure the validity of the code.

H5: How It Enhances User Experience on the WebH5: How It Enhances User Experience on the WebApr 19, 2025 am 12:08 AM

H5 improves web user experience with multimedia support, offline storage and performance optimization. 1) Multimedia support: H5 and elements simplify development and improve user experience. 2) Offline storage: WebStorage and IndexedDB allow offline use to improve the experience. 3) Performance optimization: WebWorkers and elements optimize performance to reduce bandwidth consumption.

Deconstructing H5 Code: Tags, Elements, and AttributesDeconstructing H5 Code: Tags, Elements, and AttributesApr 18, 2025 am 12:06 AM

HTML5 code consists of tags, elements and attributes: 1. The tag defines the content type and is surrounded by angle brackets, such as. 2. Elements are composed of start tags, contents and end tags, such as contents. 3. Attributes define key-value pairs in the start tag, enhance functions, such as. These are the basic units for building web structure.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

VSCode Windows 64-bit Download

VSCode Windows 64-bit Download

A free and powerful IDE editor launched by Microsoft

DVWA

DVWA

Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),