搜尋
首頁web前端H5教程你值得了解的WEB前端跨域解決方案(程式碼詳解)

之前的文章《淺析Node中zip壓縮和zip解壓縮(附程式碼)》中,給大家介紹了Node中zip壓縮和zip解壓縮指令的使用詳解。以下這篇文章給大家了解WEB前端跨域解決方案,夥伴們來看看。

你值得了解的WEB前端跨域解決方案(程式碼詳解)

WEB前端跨域解決方案

跨域定義

廣義的定義:跨域是指一個域下的文檔或腳本試圖去請求另一個網域下的資源。

1、資源跳轉:連結、重定向、表單提交

2、資源嵌入:<link><script></script><img src="/static/imghwm/default1.png" data-src="https://b.chuchur.com/b.html" class="lazy" alt="你值得了解的WEB前端跨域解決方案(程式碼詳解)" ><frame>dom標籤,還有樣式中background:url()@font-face()等檔案外鏈

3、腳本請求:js發起的ajax請求、dom js物件的跨域操作等

同源策略

#同源策略/SOP(Same origin policy )是一種約定,由Netscape公司1995 年引進瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到XSSCSFR等攻擊。所謂同源是指「協定 網域 埠」三者相同,即便兩個不同的網域指向同一個ip位址,也非同源。

同源策略限制以下幾個行為:

1、CookieLocalStorageIndexDB無法讀取

2、DOMJs物件無法獲得

3、AJAX請求不能發送

跨域解決方案

1)jsonp跨域

關於jsonp的原理把握一下幾點: 

1、html標籤的src屬性沒有同源限制(支援跨域),當瀏覽器解析script標籤時,會自動下載src屬性值(url)指向的資源;

2、script標籤指向的資源檔案下載後,其中的內容會立即執行;

3、伺服器端的程式會解析src屬性值中的url傳遞的參數,根據這些參數針對性返回一個/多個函數呼叫表達式,這些函數呼叫表達式的參數就是客戶端跨域想得到的資料;

4、伺服器產生、傳回的文件中,表達式呼叫的函數是已經在本地提前定義好的,而參數就是希望從跨域伺服器拿到的資料。字面上的script標籤可以,動態加入到dom樹中的script也可以,後者更方便綁定事件。

5、只能實作get,也是他的弱點

#實作:
##

// 服务端返回:
test({
  code: 0,
  message: "成功",
});
<!-- 原生js -->
<script>
  var script = document.createElement("script");
  script.type = "text/javascript";
  // 传参并指定回调执行函数为callback
  script.src = "http://www.chuchur.com/login?callback=test";
  document.head.appendChild(script);
  // 回调执行函数
  function test(res) {
    console.log(JSON.stringify(res));
  }
</script>
//jquery ajax:
$.ajax({
  url: "http://www.chuchur.com/login",
  type: "get",
  dataType: "jsonp", // 请求方式为jsonp
  jsonpCallback: "test", // 自定义回调函数名
  data: {},
});

//vue.js
this.$http
  .jsonp("http://www.chuchur.com/login", {
    params: {},
    jsonp: "test",
  })
  .then((res) => {
    console.log(res);
  });

2)document.domain iframe 跨域

#原理:這個方案只限於主域相同,子域不同的情況,其原理就是兩個頁面透過js強制設定window.domain為主域,這樣就實現了同域。

實作:

<!-- 父窗口 https://www.chuchur.com/a.html -->
<iframe id="iframe" ></iframe>
<script>
  document.domain = "chuchur.com";
  var user = "chuchur";
</script>
<!-- 子窗口 https://b.chuchur.com/b.html -->
<script>
  document.domain = "chuchur.com";
  // 获取父窗口中变量
  alert("从父窗口取得数据" + window.parent.user);
</script>

3)location.hash iframe跨域

##原理

: 其原理就是透過URL傳值,然後監聽其hash值的變化,然後透過中間層做跳板,再利用父子視窗js parent最後來存取同域所有頁面物件。 網域

1: a.html

,網域 2:b.html ,網域 1:c.html

a.html

b.html 不同網域只能透過hash傳值通訊。

b.html

c.html 也不同網域也只能單項通訊

a.html

c.html 同域,所以c.html可以透過parent來存取a.html頁面物件

實作

1、

a.html:(www.chuchur.com/a.html) 

<iframe
  id="iframe"
  src="http://www.chuchur.org/b.html"
  style="display:none; "
></iframe>
<script>
  var iframe = document.getElementById("iframe");
  // 向b.html传hash值
  setTimeout(function () {
    iframe.src = iframe.src + "#nick=chuchur";
  }, 1000);
  // 开放给同域c.html的回调方法
  function test(res) {
    alert("数据来自c.html ---> " + res);
  }
</script>
`

2、

b.html:(www.chuchur.org/b.html) #

<iframe
  id="iframe"
  src="http://www.chuchur.com/c.html"
  style="display:none; "
></iframe>
<script>
  var iframe = document.getElementById("iframe");
  // 监听a.html传来的hash值,再传给c.html
  window.onhashchange = function () {
    iframe.src = iframe.src + location.hash;
  };
</script>

3、

c.html:(www. chuchur.com/c.html)

<script>
  // 监听b.html传来的hash值
  window.onhashchange = function () {
    // 再通过操作同域a.html的js回调,将结果传回
    window.parent.parent.test("你好: " + location.hash.replace("#nick=", ""));
  };
</script>

4)

window.name iframe跨域

原理

:利用window.name特有屬性,name值在不同的頁面甚至不同域,當頁面重新載入後依然存在,並且支援非常長的值,約2MB

實作

// 1.)a.html:(www.chuchur.com/a.html)
var proxy = function (url, callback) {
  var state = 0;
  var iframe = document.createElement("iframe");
  // 加载跨域页面 ,先让页面的name执行赋值,
  iframe.src = url;
  // onload事件会触发2次,第1次加载跨域页,并留存数据于window.name
  iframe.onload = function () {
    if (state === 1) {
      // 第2次onload(同域proxy页)成功后,读取同域window.name中数据
      test(iframe.contentWindow.name);
      destoryFrame();
    } else if (state === 0) {
      // 第1次onload(跨域页)成功后,切换到同域代理页面
      iframe.contentWindow.location = "http://www.chuchur.com/b.html";
      state = 1;
    }
  };
  document.body.appendChild(iframe);
  // 获取数据以后销毁这个iframe,释放内存;这也保证了安全(不被其他域frame js访问)
  function destoryFrame() {
    iframe.contentWindow.document.write("");
    iframe.contentWindow.close();
    document.body.removeChild(iframe);
  }
};

// 请求跨域b页面数据
proxy("http://www.domain2.com/b.html", function (data) {
  alert(data);
});
// 2.)proxy.html:(www.chuchur.com/proxy.html), 这个页面可以什么都不写,但是要保证能正常访问
<!-- 3.)b.html:(www.chuchur.org/b.html) -->
<script>
  window.name = "我是一个可以非常长的变量";
</script>

5)

postMessage跨網域

postMessage

HTML5 XMLHttpRequest Level 2中的API,可以解決以下方面的問題:

a.)

頁面和其開啟的新視窗的資料傳遞

b.)

多重視窗之間訊息傳遞<p><code>c.)页面与嵌套的iframe消息传递

d.)上面三个场景的跨域数据传递 用法:postMessage(data, origin)方法接受两个参数

data:html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。

origin: 协议+主机+端口号,也可以设置为"\*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

实现:

<!-- 1.)a.html:(www.chuchur.com/a.html) -->
<iframe
  id="iframe"
  src="http://www.chuchur.com/b.html"
  style="display:none; "
></iframe>
<script>
  var iframe = document.getElementById("iframe");
  iframe.onload = function () {
    var data = {
      name: "邱秋",
    };
    // 向chuchur.org传送跨域数据
    iframe.contentWindow.postMessage(
      JSON.stringify(data),
      "http://www.chuchur.org"
    );
  };

  // 接受chuchur.org返回数据
  window.addEventListener(
    "message",
    function (e) {
      alert("我来自chuchur.org: " + e.data);
    },
    false
  );
</script>
<!-- 2.)b.html:(www.chuchur.org/b.html) -->
<script>
  // 接收chuchur.com的数据
  window.addEventListener(
    "message",
    function (e) {
      alert("我来自chuchur.com " + e.data);
      var data = JSON.parse(e.data);
      if (data) {
        data.nick = chuchur;
        // 处理后再发回chuchur.com
        window.parent.postMessage(
          JSON.stringify(data),
          "http://www.chuchur.org"
        );
      }
    },
    false
  );
</script>

6)跨域资源共享(CORS

原理:普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置。

cookie请求:前后端都需要设置字段,另外需注意:所带cookie为跨域请求接口所在域的cookie,而非当前页。 目前,所有浏览器都支持该功能(IE8+:IE8/9需要使用XDomainRequest对象来支持CORS),CORS也已经成为主流的跨域解决方案。

实现:

//1)原生js
var xhr = new XMLHttpRequest(); // IE8/9需用window. XDomainRequest兼容

// 前端设置是否带cookie
xhr.withCredentials = true;
xhr.open(&#39;post&#39;, &#39;http://www.chuchur.com/login&#39;, true);
xhr.setRequestHeader(&#39;Content-Type&#39;, &#39;application/x-www-form-urlencoded&#39;);
xhr.send(&#39;user=chuchur&#39;);
xhr.onreadystatechange = function() {

  if (xhr.readyState == 4 && xhr.status == 200) {
    alert(xhr.responseText);
  }

};
//2.)jQuery ajax
$.ajax({
  ...
  xhrFields: {
    withCredentials: true // 前端设置是否带cookie
  },
  crossDomain: true, // 会让请求头中包含跨域的额外信息,但不会含cookie
  ...
});
//3.)vue框架在vue-resource封装的ajax组件中加入以下代码:
Vue.http.options.credentials = true

//后台服务端
//java
/*
 * 导入包:import javax.servlet.http. HttpServletResponse;
 * 接口参数中定义:HttpServletResponse response
 */
response.setHeader("Access-Control-Allow-Origin", "http://www.chuchur.com"); // 若有端口需写全(协议+域名+端口)
response.setHeader("Access-Control-Allow-Credentials", "true");

//node
var server = http.createServer();
server.on(&#39;request&#39;, function(req, res) {
  var postData = &#39;&#39;;
  // 数据块接收中
  req.addListener(&#39;data&#39;, function(chunk) {
    postData += chunk;
  });

  // 数据接收完毕
  req.addListener(&#39;end&#39;, function() {
    postData = qs.parse(postData);
    // 跨域后台设置
    res.writeHead(200, {
      &#39;Access-Control-Allow-Credentials&#39;: &#39;true&#39;, // 后端允许发送Cookie
      &#39;Access-Control-Allow-Origin&#39;: &#39;http://www.chuchur.com&#39;, // 允许访问的域(协议+域名+端口)
      &#39;Set-Cookie&#39;: &#39;l=abcdef; Path=/; Domain=www.chuchur.com; HttpOnly&#39; // HttpOnly: 脚本无法读取cookie
    });

    res.write(JSON.stringify(postData));
    res.end();

  });

});
server.listen(&#39;3000&#39;);

7)nginx反向代理跨域

浏览器跨域访问jscssimg等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。

location / { add_header Access-Control-Allow-Origin *; }

原理:通过nginx代理一个 同域不同端口的跳板机,反向代理要跨域的域名,这样可以修改cookie里面的domain信息实现跨域

实现:

#nginx具体配置:
server {

    listen       80;
    server_name  www.chuchur.com;
    location / {
        proxy_pass   http://www.chuchur.org; #反向代理
        proxy_cookie_domain www.chuchur.org www.chuchur.com; #修改cookie里域名
        index  index.html index.htm;

        # 当用webpack-dev-server等中间件代理接口访问nignx时,此时无浏览器参与,故没有同源限制,下面的跨域配置可不启用
        add_header Access-Control-Allow-Origin http://www.chuchur.com; #当前端只跨域不带cookie时,可为*
        add_header Access-Control-Allow-Credentials true;
    }

}

前端实现

var xhr = new XMLHttpRequest();
// 前端开关:浏览器是否读写cookie
xhr.withCredentials = true;
// 访问nginx中的代理服务器
xhr.open(&#39;get&#39;, &#39;http://www.chuchur.com/?user=chuchur&#39;, true);
xhr.send();

// node
var http = require(&#39;http&#39;);
var server = http.createServer();
var qs = require(&#39;querystring&#39;);
server.on(&#39;request&#39;, function(req, res) {

  var params = qs.parse(req.url.substring(2));
  // 向前台写cookie
  res.writeHead(200, {

    &#39;Set-Cookie&#39;: &#39;l=abcdef; Path=/; Domain=www.chuchur.org; HttpOnly&#39; // HttpOnly: 脚本无法读取

  });
  res.write(JSON.stringify(params));
  res.end();

});
server.listen(&#39;8080&#39;);

8)Nodejs中间件代理跨域

原理同nignx代理跨域类似,都是通过代理服务器实现数据转发

实现:

//1)利用中间件http-proxy-middleware实现
var express = require(&#39;express&#39;);
var proxy = require(&#39;http-proxy-middleware&#39;);
var app = express();

app.use(&#39;/&#39;, proxy({

  // 代理跨域目标接口
  target: &#39;http://www.chuchur.org:&#39;,
  changeOrigin: true,
  // 修改响应头信息,实现跨域并允许带cookie
  onProxyRes: function(proxyRes, req, res) {

    res.header(&#39;Access-Control-Allow-Origin&#39;, &#39;http://www.chuchur.com&#39;);
    res.header(&#39;Access-Control-Allow-Credentials&#39;, &#39;true&#39;);

  },

  // 修改响应信息中的cookie域名
  cookieDomainRewrite: &#39;www.chuchur.com&#39; // 可以为false,表示不修改

}));

app.listen(3000);
//2)利用中间件 webpack-dev-server实现
//webpack.config.js部分配置:
module.exports = {
  entry: {},
  module: {},
  ...
  devServer: {
    historyApiFallback: true,
    proxy: [{
      context: &#39;/login&#39;,
      target: &#39;http://www.chuchur.org&#39;, // 代理跨域目标接口
      changeOrigin: true,
      cookieDomainRewrite: &#39;www.chuchur.com&#39; // 可以为false,表示不修改
    }],
    noInfo: true

  }
}

9)WebSocket协议跨域

WebSocket protocolHTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

实现:

1、前端代码

<div>user input:<input type="text" /></div>
<script src="./socket.io.js"></script>
<script>
  var socket = io("http://www.chuchur.org");

  // 连接成功处理
  socket.on("connect", function () {
    // 监听服务端消息
    socket.on("message", function (msg) {
      console.log("来自服务器的消息: " + msg);
    });

    // 监听服务端关闭
    socket.on("disconnect", function () {
      console.log("Server socket has closed.");
    });
  });

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

2、Nodejs socket后台:

var http = require(&#39;http&#39;);
var socket = require(&#39;socket.io&#39;);

// 启http服务
var server = http.createServer(function(req, res) {
  res.writeHead(200, {
    &#39;Content-type&#39;: &#39;text/html&#39;
  });
  res.end();
});

server.listen(&#39;8080&#39;);
console.log(&#39;Server is running at port 8080... &#39;);

// 监听socket连接
socket.listen(server).on(&#39;connection&#39;, function(client) {

      // 接收信息
      client.on(&#39;message&#39;, function(msg) {
          client.send(&#39;哈哈:&#39; + msg);
          console.log(&#39;来自客服端的消息&#39;: -- - > &#39; + msg);
          });

        // 断开处理
        client.on(&#39;disconnect&#39;, function() {
          console.log(&#39;Client socket has closed.&#39;);
        });

      });

以上 9 种方式都能实现跨域数据传递,用的最多的还是第六种跨域资源共享(CORS),在前后端分离开发模式最常见。第七种和第八种中间件代理实现方式则是在基于node开发种常用的

其中第二,三、四、五种方案 ,利用ifamepostMessage则可以实现 不同窗口之间的数据通讯。

【完】

推荐学习:H5视频教程

以上是你值得了解的WEB前端跨域解決方案(程式碼詳解)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:禅境花园。如有侵權,請聯絡admin@php.cn刪除
H5:網絡內容和設計的未來H5:網絡內容和設計的未來May 01, 2025 am 12:12 AM

H5(HTML5)將通過新元素和API提升網頁內容和設計。 1)H5增強了語義化標記和多媒體支持。 2)它引入了Canvas和SVG,豐富了網頁設計。 3)H5的工作原理是通過新標籤和API擴展HTML功能。 4)基本用法包括使用創建圖形,高級用法涉及WebStorageAPI。 5)開發者需注意瀏覽器兼容性和性能優化。

H5:網絡開發的新功能和功能H5:網絡開發的新功能和功能Apr 29, 2025 am 12:07 AM

H5帶來了多項新功能和能力,極大提升了網頁的互動性和開發效率。 1.語義化標籤如、增強了SEO。 2.多媒體支持通過和標籤簡化了音視頻播放。 3.Canvas繪圖提供了動態圖形繪製工具。 4.本地存儲通過localStorage和sessionStorage簡化了數據存儲。 5.地理位置API便於開發基於位置的服務。

H5:HTML5的關鍵改進H5:HTML5的關鍵改進Apr 28, 2025 am 12:26 AM

HTML5帶來了五個關鍵改進:1.語義化標籤提升了代碼清晰度和SEO效果;2.多媒體支持簡化了視頻和音頻嵌入;3.表單增強簡化了驗證;4.離線與本地存儲提高了用戶體驗;5.畫布與圖形功能增強了網頁的可視化效果。

HTML5:標準及其對Web開發的影響HTML5:標準及其對Web開發的影響Apr 27, 2025 am 12:12 AM

HTML5的核心特性包括語義化標籤、多媒體支持、離線存儲與本地存儲、表單增強。 1.語義化標籤如、等,提升代碼可讀性和SEO效果。 2.和標籤簡化多媒體嵌入。 3.離線存儲和本地存儲如ApplicationCache和LocalStorage,支持無網絡運行和數據存儲。 4.表單增強引入新輸入類型和驗證屬性,簡化處理和驗證。

H5代碼示例:實際應用和教程H5代碼示例:實際應用和教程Apr 25, 2025 am 12:10 AM

H5提供了多種新特性和功能,極大地增強了前端開發的能力。 1.多媒體支持:通過和元素嵌入媒體,無需插件。 2.畫布(Canvas):使用元素動態渲染2D圖形和動畫。 3.本地存儲:通過localStorage和sessionStorage實現數據持久化存儲,提升用戶體驗。

H5和HTML5之間的連接:相似性和差異H5和HTML5之間的連接:相似性和差異Apr 24, 2025 am 12:01 AM

H5和HTML5是不同的概念:HTML5是HTML的一個版本,包含新元素和API;H5是基於HTML5的移動應用開發框架。 HTML5通過瀏覽器解析和渲染代碼,H5應用則需要容器運行並通過JavaScript與原生代碼交互。

H5代碼的基礎:密鑰元素及其目的H5代碼的基礎:密鑰元素及其目的Apr 23, 2025 am 12:09 AM

HTML5的關鍵元素包括、、、、、等,用於構建現代網頁。 1.定義頭部內容,2.用於導航鏈接,3.表示獨立文章內容,4.組織頁面內容,5.展示側邊欄內容,6.定義頁腳,這些元素增強了網頁的結構和功能性。

HTML5和H5:了解常見用法HTML5和H5:了解常見用法Apr 22, 2025 am 12:01 AM

HTML5和H5沒有區別,H5是HTML5的簡稱。 1.HTML5是HTML的第五個版本,增強了網頁的多媒體和交互功能。 2.H5常用於指代基於HTML5的移動網頁或應用,適用於各種移動設備。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

EditPlus 中文破解版

EditPlus 中文破解版

體積小,語法高亮,不支援程式碼提示功能

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )專業的PHP整合開發工具

SecLists

SecLists

SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境