跨域的十種方式

一. josnp 只支持 get 方法,原理是引入經過 src 引入 scriptjavascript

  • 後端代碼
//後端須要取到前端傳遞過來的回調函數名稱和參數
app.get('/cors', function(req, res) {
  let { cb, wd } = req.query;
  res.send(`${cb}({data:"你好"})`);
});
  • 前端代碼
$.ajax({
  url: 'http://localhost:3000/cors',
  type: 'GET',
  dataType: 'jsonp',
  data: {
    wd: '你好'
  },
  jsonp: 'cb',
  success: function(data) {
    console.log(data);
  }
});

二. cors 跨域
跨域資源共享 cross-origin resoure sharing
須要後端配置才能夠 能夠支持全部方法
簡單請求 直接容許 post 和 get 跨域
複雜請求發送的時候 會先發一個預檢請求(先問服務器支持不支持發送請求的類型)
預檢請求 => OPTIONS
三. postmessage+iframe 跨域html

  • data:顧名思義,是傳遞來的消息
  • source:發送消息的窗口對象
  • origin:發送消息窗口的源(協議+主機+端口號)
  • 確保 a、b 頁面能訪問
  • http://localhost:3000/a.html
  • http://localhost:4000/b.html
<!-- 頁面引入b頁面 -->
<iframe
  id="frame"
  src="http://localhost:4000/b.html"
  frameborder="0"
  onload="load()"
></iframe>
<script>
  load = () => {
    let frame = document.getElementById('frame');
    frame.contentWindow.postMessage('你是好人', 'http://localhost:4000');
    window.onmessage = function(e) {
      console.log(e.data);
    };
  };
  //我是b頁面
  window.onmessage = function(e) {
    console.log(e.data);
    e.source.postMessage('你是壞人', e.origin);
  };
</script>

四. docmument.domain 只適合使用在二級域名的狀況前端

window hots 目錄 c:\windows\system32\drivers\etc
mac 在 /etc/hosts 設置二級域名
hosts 文件設置
127.0.0.1 www.ry.com
127.0.0.1 vip.ry.com
127.0.0.1 svip.ry.com
//能夠經過如下 3 個地址進行訪問
http://www.ry.com:4000/b.html
http://vip.ry.com:4000/b.html
http://svip.ry.com:4000/b.html
qq.com 一級域名 vip.qq.com music.qq.com qq 的二級域名
<!-- 訪問的頁面http://vip.ry.com:3000/a.html  http://svip.ry.com:4000/b.html -->
<!-- 1.a頁面引入b頁面 -->
<iframe
  src="http://svip.ry.com:4000/b.html"
  frameborder="0"
  onload="load()"
  id="frame"
></iframe>
//2. b頁面設置全局變量和一級域名
<script>
  document.domain = 'ry.com';
  window.a = '你好';
</script>
//3. a頁面設置一級域名而且在iframe
加載完成後調用load方法經過frame.contentWindow.a 拿到b頁面的全局變量
<script>
  document.domain = 'ry.com';
  function load() {
    console.log(frame.contentWindow.a);
  }
</script>

五. websoket 雙工協議vue

//file:///Users/ruanye/Desktop/cross-domain/5.websocket/index.html
//前端 通常用socket.io進行兼容
let socket = new WebSocket('ws:localhost:3000');
    socket.onopen=function(){
        socket.send('你好')
    }
    socket.onmessage=function(e){
      console.log(e.data)
 }
//後端  npm install ws
let express = require('express');
let app = express();
let Websocket =require('ws');
<!-- 建立websoket服務器 -->
let wss = new Websocket.Server({port:3000})
<!-- 建立鏈接和發送消息 -->
wss.on('connection',function(ws){
    ws.on('message',function(data){
      console.log(data)
      ws.send('你也好')
    })
})

六. webpack 代理java

vue-cli 2.0
    config/index.js
    proxyTable: {
      '/':{
        target:'http://localhost:3000',
        changeOrigin:true,
        pathRewrite:{
          '^/':'/'
        }
      }
    }
    config/dev.env.js
    module.exports = merge(prodEnv, {
      NODE_ENV: '"development"',
      API_HOST:'/' // +須要加API_HOST
   })
   // vue-cli3.0在vue.config.js裏面進行配置
    devServer: {
       proxy: 'http://localhost:3000'
     }

七. node 中間層代理node

//服務端訪問服務端不存在跨域
// 接口端服務器代碼(axios在node裏面也能夠使用)
app.get('/nodecors', function(req, res) {
  res.send('1234');
});
//客戶端代碼 客戶端在客戶端的服務器裏面用axios請求請求接口服務器
app.get('/a', async function(req, res) {
  let data = await axios.get('http://localhost:3000/nodecors');
  let result = data.data;
  res.json(result);
});

八. window.name + iframe 跨域webpack

//a頁面、b頁面 同一個域名 c頁面本身一個域名
    //a獲取c的數據,a先引用c c把值放在window.name上,iframe加載完成後把a的引用地址改到b
    // a頁面  firame的window.name並無改變
    //firstload 防止死循環
    let firstload = true;
    function load(){
        let frame= document.getElementById('frame');
       if(firstload){
            frame.src ='http://localhost:3000/b.html';
           firstload = false;

        }else{
            console.log(frame.contentWindow.name)
    }
   //b頁面
   //c頁面
  window.name = '你好'

九. location.hash+ iframe
`有 a、b、c 三個頁面 a、b 同域 c 是獨立域ios

  • a 頁面經過 iframe 引入 c 頁面,而且傳入一個 hash 值 #name
  • c 動態建立 ifame,iframe 的 src 是 b 頁面,c 經過 ifrmae 把 hash 值傳遞給 b,把 ifram 添加到 dom 裏面
  • b 頁面--> 父親--> c 頁面-->父親-->a 頁面
  • c 頁面能夠經過 b 頁面的 location.hash 拿到 c 傳給 b 的 hash 值
  • b 頁面將拿到 hash 放到 a 的 hash 值中
  • a 頁面監聽 hash 值改變事件能拿到 c 傳過來 hash 值
let iframe = document.createElement('iframe');
iframe.src = 'http://localhost:3000/b.html#youare';
document.body.appendChild(iframe);
//b 頁面 放值
window.parent.parent.location.hash = location.hash;
//a頁面監聽
window.onhashchange = function() {
  console.log(location.hash);
};

十. nginx 反向代理nginx

- 須要 3 個端口 服務端 nginx 服務器 靜態文件服務器  
window conf 文件夾裏面 找到 nginx.conf
- nignx 不能在任何中文目錄裏面
- mac 前往 /usr/local/etc/nginx
- http 裏面 server 表示虛擬服務器器
- server_name www.ruanye.com
- ping 命令加域名 能夠測試鏈接 `ping www.baidu.com`
- server
  listen 80 監聽端口號
  server_name 虛擬服務器的名字
- nginx 命令
  - nginx #啓動
  - 從新加載 nginx -s reload
  - 退出 nginx -s quit
//配置跨域頭
http {
  ###start####
  // 容許什麼域名進行跨域
  add_header Access-Control-Allow-Origin *;
  // 容許什麼頭進行跨域
  add_header Access-Control-Allow-Headers X-Requested-With;
  //容許什麼方法進行跨域
  add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
  ###end ###
}
//配置代理的域名 proxy_pass 須要代理的域名
 server {
        listen 8080;
        server_name  www.ai.com;
        location / {
        proxy_pass http://localhost:3000;
        root   html;
        index  index.html index.htm;
   }
 http://localhost:8080/cors

npm install nodemon -g
node 有改動自動自動重啓web

相關文章
相關標籤/搜索