「跨域」應用node.js實踐前端種種跨域體式格局(下)

媒介

常言道,”讀萬卷書,不如行萬里路”。手藝的進修也是云云,惟有實踐才更清晰的邃曉道理和加深印象,因而本文會應用node.js對前端的種種跨域體式格局舉行實踐,強烈建議一步一步隨着做,相信你一定會對跨域有更深條理的明白。而由於篇幅限定,本文只會貼出關鍵性的代碼,本系列統共分為上下篇。詳細的代碼請移步我的Github。假如對你有協助的話,迎接 star ヾ(´・ω・`)ノ

接上文—>「跨域」應用node.js實踐前端種種跨域體式格局(上)

六、window.postMessage

postMessage是HTML5 XMLHttpRequest Level 2中的API,且是為數不多能夠跨域操縱的window屬性之一,它可用於處置懲罰以下方面的題目:

1.頁面和其翻開的新窗口的數據通報
2.多窗口之間音訊通報
3.頁面與嵌套的iframe音訊通報
4.上面三個場景的跨域數據通報

用法:postMessage(data,origin)要領吸收兩個參數
data: html5範例支撐恣意基礎範例或可複製的對象,但部份瀏覽器只支撐字符串,所以傳參時最好用JSON.stringify()序列化。
origin: 協定+主機+端口號,也能夠設置為”*”,示意能夠通報給恣意窗口,假如要指定和當前窗口同源的話設置為”/”。

來,我們來用node.js實踐一下~

目次:postMessage/public/a.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>a</title>
    <iframe id="iframe" src="http://localhost:4444/b.html" style="display:none;"></iframe>
</head>
<body>
    <script>
        const iframe = document.getElementById('iframe');
        iframe.onload = function() {
            const data = {
                name : 'Jchermy'
            };

            //向http://localhost:4444 發送跨域數據
            iframe.contentWindow.postMessage(JSON.stringify(data), "http://localhost:4444");
        };

        //吸收 localhost:4444 返回的數據
        window.addEventListener('message', function(e){
            alert('data from b.html ----->' + e.data);
        },false);
    </script>
</body>
</html>

在iframe加載完成后,向b.html地點域發送數據。由於postMessage是綁定在window對象上的,所以我們要獵取iframe.contentWindow再發送數據,同時監聽message,視察b.html有無回傳數據給我們。如今分別跑兩個效勞。接見localhost:3333能夠看到:
《「跨域」應用node.js實踐前端種種跨域體式格局(下)》

b.html吸收到a.html發送過去的數據啦~

《「跨域」應用node.js實踐前端種種跨域體式格局(下)》

然後a.html也收到了b.html回傳的數據了。

跨域勝利~ ( 。ớ ₃ờ)ھ

七、nginx 反向代辦

這個計劃的道理圖以下:

《「跨域」應用node.js實踐前端種種跨域體式格局(下)》

申明:當A域想與B域通信,能夠經由過程nginx的反向代辦,起首A域與同域的nginx效勞器通信,然後nginx將要求轉發到別的一個效勞器,由於效勞器之間的通信不存在跨域,如許我們就完成了跨域。詳細完成以下:

起首,假如當地沒有裝置nginx的,須要裝置nginx。裝置完成后,我們對nginx舉行設置:

目次:nginx-1.14.0/conf/nginx.conf

    server {
        listen       1111;
        server_name  localhost;

        location / {
            proxy_pass http://localhost:9999/; #反向代辦到9999端口
            index  index.html index.htm;
            default_type "text/html";
            alias  "D:/Github/node-server/nginx/public/"; #client.html地點的當地的地點

            add_header Access_Control_Allow_Origin http://localhost:1111; 
            add_header Access_Control_Allow_Credentials true; #許可客戶端帶cookie接見
        }

然後,我們設置9999端口的效勞器

目次:nginx/server.js

const http = require('http');
const server = http.createServer();
const qs = require('querystring');

server.on('request', function(req, res) {
    const query = require('url').parse(req.url, true).query;

    //向前台寫cookie
    res.writeHead(200, {
        'Set-Cookie' : 'name=jchermy;Path:/;Domain:localhost;Httponly' //HttpOnly 劇本沒法讀取
    });
   
    res.write(JSON.stringify('Hi! '+query.user));
    res.end();
})

server.listen('9999');
console.log('Server is running at port 9999 .....');

這時候,我們翻開瀏覽器,接見 http://localhost:1111/client.html?user=jchermy,看到下面的頁面:

《「跨域」應用node.js實踐前端種種跨域體式格局(下)》

我們在1111端口,將user=jchermy傳給9999端口,然後9999端口吸收到了我們的發送的信息並回傳了"Hi! jchermy".申明這兩個url能夠跨域互相通信!完成~

七、node.js 中間件跨域

這個計劃與nginx反向代辦非常相似,只是將nginx代辦效勞器換成了node效勞器。

目次:node-middleware/proxyserver.js

const express = require('express');
const proxy = require('http-proxy-middleware');
const app = express();

app.use('/login', proxy({
    //代辦跨域的目的接口
    target: 'http://localhost:5555',
    changeOrigin: true,
    //修正相應頭信息,完成跨域,並許可帶cookie
    onProxyRes: function(proxyRes, req, res) {
        res.header('Access-Control-Allow-Origin', 'http://localhost');
        res.header('Access-Control-Allow-Credentials', 'true');
    },

    //修正相應信息中的cookie域名
    cookieDomainRewrite: 'http://localhost'
}));

app.use(express.static( './public'));
app.listen(3333);
console.log('proxy server is listen at port 3333');

目次:node-middleware/server.js

const http = require('http');
const server = new http.Server();
const qs = require('querystring');

server.on('request', function(request, response) {
    const query = require('url').parse(request.url, true).query;
    response.writeHead(200, {
        'Set-Cookie': 'name=amiee;Path:/;Domain:localhost:3333;Httponly'
    });

    response.write(`Hi, ${query.name} ! I come from localhost:5555`);
    response.end();
})

server.listen('5555');
console.log('Server is running at port 5555 .....')

末了,接見http://localhost:3333/login?name=hahah,能夠看到:
《「跨域」應用node.js實踐前端種種跨域體式格局(下)》

八、webSocket

WebSocket protocol是HTML5一種新的協定。它完成了瀏覽器與效勞器全雙工通信,同時許可跨域通信,是server push手藝的一種很好的完成。
原生WebSocket API運用起來不太輕易,我們運用Socket.io,它很好地封裝了webSocket接口,供應了更簡樸、天真的接口,也對不支撐webSocket的瀏覽器供應了向下兼容。

起首,我們建立一個客戶端的html頁面。

目次:webSocket/public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>index</title>
</head>
<body>
    <div>用戶輸入: <input type="text"></div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
    <script>
        window.onload = function(){
            var socket = io('http://localhost:5555');

            //銜接勝利處置懲罰
            socket.on('connect', function(){
                console.log('Server socket has established');
            });

            socket.on('disconnect', function() {
                console.log('Server sockect has closed');
            });

            //監聽效勞端音訊
            socket.on('message', function(msg) {
                console.log('data from server ---->' +msg);
            } )

            document.getElementsByTagName('input')[0].onblur = function() {
                socket.send(this.value);
            };
        }
    </script>
</body>
</html>

將這個頁面布置在3333端口上。

目次:webSocket/client.js

const express = require('express');
const app = express();

app.use(express.static('./public'));
app.listen(3333);
console.log('client is running at port 3333....');

末了,建立一個效勞器,吸收客戶端的要求,並賦予返回值

目次: webSocket/server.js

const http = require('http');
const socket = require('socket.io');
 
//啟動http效勞
const server = http.createServer(function(req, res) {
    res.writeHead(200, {
        'Content-type': 'text/html'
    });
    res.end();
})

server.listen(5555);
console.log('server is running at port 5555');

const io = socket(server);
//監聽socket銜接
io.on('connection', function (client) {
    //吸收音訊
    client.on('message', function (msg) {
        io.emit('message',  `hello, ${msg}`);
        console.log('data from client --->' + msg);
      });

      //斷開處置懲罰
      client.on('disconnect', function() {
          console.log('Client socket has closed');
      });
});

將客戶端和效勞器端都跑起來,輸入一些字符,當鼠標落空核心后能夠在效勞器端5555端口的控制台看到:
《「跨域」應用node.js實踐前端種種跨域體式格局(下)》

這申明效勞器已收到了客戶端發送過去的字符。

此時在翻開客戶端頁面的控制台,能夠看到客戶端也收到了效勞器返回的字符:
《「跨域」應用node.js實踐前端種種跨域體式格局(下)》

結語

這個系列終究寫完啦,照樣那句話,有毛病和不合理的處所迎接人人斧正!假如文章對你有協助的話,迎接點贊珍藏!!Github給個star就最好啦!=(//▽//)謝謝人人~

    原文作者:Jchermy
    原文地址: https://segmentfault.com/a/1190000015276949
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞