跨域:指的是瀏覽器不能執行其餘網站的腳本。它是由瀏覽器的同源策略形成的,是瀏覽器對 javascript 施加的安全限制。javascript
同源策略:是指協議,域名,端口都要相同,其中有一個不一樣都會產生跨域。css
做者信息
github: https://github.com/Michael-lzg
掘金: https://juejin.im/post/5e0d4b...html
雖然如今大部分項目並不會使用它來解決跨域,可是隻要是面試,涉及到跨域,基本都會問到這個知識點。他說利用 script 標籤自然跨域的特性。前端
缺點:只能使用 get 請求,不推薦使用vue
原生實現java
<script> var script = document.createElement('script'); script.type = 'text/javascript'; // 傳參一個回調函數名給後端,方便後端返回時執行這個在前端定義的回調函數 script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback'; document.head.appendChild(script); // 回調執行函數 function handleCallback(res) { alert(JSON.stringify(res)); } </script> <!-- 服務端返回以下(返回時即執行全局函數): --> handleCallback({"status": true, "user": "admin"}) 複製代碼
jquery ajax:node
$.ajax({ url: 'http://www.demo2.com:8080/login', type: 'get', dataType: 'jsonp', // 請求方式爲jsonp jsonpCallback: 'onBack', // 自定義回調函數名 data: {} })
vue.js:jquery
this.$http .jsonp('http://www.demo2.com:8080/login', { params: {}, jsonp: 'onBack' }) .then(res => { console.log(res) })
使用 web 服務器的反向代理設置,這不是先後端跨域解決方案,而是屬於運維層級的。webpack
一、nginx配置解決iconfont跨域 瀏覽器跨域訪問js、css、img等常規靜態資源被同源策略許可,但iconfont字體文件(eot|otf|ttf|woff|svg)例外,此時可在nginx的靜態資源服務器中加入如下配置。nginx
location / { add_header Access-Control-Allow-Origin *; }
二、nginx反向代理接口跨域 跨域原理: 同源策略是瀏覽器的安全策略,不是HTTP協議的一部分。服務器端調用HTTP接口只是使用HTTP協議,不會執行JS腳本,不須要同源策略,也就不存在跨越問題。
實現思路:經過nginx配置一個代理服務器(域名與domain1相同,端口不一樣)作跳板機,反向代理訪問domain2接口,而且能夠順便修改cookie中domain信息,方便當前域cookie寫入,實現跨域登陸。
#proxy服務器 server { listen 81; server_name www.domain1.com; location / { proxy_pass http://www.domain2.com:8080; #反向代理 proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie裏域名 index index.html index.htm; # 當用webpack-dev-server等中間件代理接口訪問nignx時,此時無瀏覽器參與,故沒有同源限制,下面的跨域配置可不啓用 add_header Access-Control-Allow-Origin http://www.domain1.com; #當前端只跨域不帶cookie時,可爲* add_header Access-Control-Allow-Credentials true; } }
當下項目中若是涉及到跨域,實際上都應該是後端經過設置 CORS 來解決的。CORS 是目前最主流的跨域解決方案,跨域資源共享(CORS) 是一種機制,它使用額外的 HTTP 頭來告訴瀏覽器 讓運行在一個 origin (domain) 上的 Web 應用被准許訪問來自不一樣源服務器上的指定的資源。
// 在node端設置一下請求頭,容許接收全部源地址的請求 res.header('Access-Control-Allow-Origin', '*') res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') res.header('Access-Control-Allow-Headers', '*')
利用 node + webpack + webpack-dev-server 代理接口跨域。在開發環境下,因爲 vue 渲染服務和接口代理服務都是 webpack-dev-server 同一個,因此頁面與代理接口之間再也不跨域,無須設置 headers 跨域信息了。webpack.config.js 部分配置:
module.exports = { entry: {}, module: {}, ... devServer: { historyApiFallback: true, proxy: [{ context: '/login', target: 'http://www.demo2.com:8080', // 代理跨域目標接口 changeOrigin: true, secure: false, // 當代理某些https服務報錯時用 cookieDomainRewrite: 'www.demo1.com' // 能夠爲false,表示不修改 }], noInfo: true } }
此方案僅限主域相同,子域不一樣的跨域應用場景。
實現原理:兩個頁面都經過 js 強制設置 document.domain 爲基礎主域,就實現了同域。
父窗口:(www.domain.com/a.html)
<iframe id="iframe" src="http://child.domain.com/b.html"></iframe> <script> document.domain = 'domain.com' var user = 'admin' </script>
子窗口:(child.domain.com/b.html)
<script> document.domain = 'domain.com' // 獲取父窗口中變量 alert('get js data from parent ---> ' + window.parent.user) </script>
postMessage 是 HTML5 XMLHttpRequest Level 2 中的 API,且是爲數很少能夠跨域操做的 window 屬性之一,它可用於解決如下方面的問題:
<iframe id="iframe" src="http://www.domain2.com/b.html" style="display:none;"></iframe> <script> var iframe = document.getElementById('iframe') iframe.onload = function() { var data = { name: 'aym' } // 向domain2傳送跨域數據 iframe.contentWindow.postMessage(JSON.stringify(data), 'http://www.domain2.com') } // 接受domain2返回數據 window.addEventListener('message',function(e) { alert('data from domain2 ---> ' + e.data) },false) </script>
b.html:(www.domain2.com/b.html)
<script> // 接收domain1的數據 window.addEventListener('message',function(e) { alert('data from domain1 ---> ' + e.data) var data = JSON.parse(e.data) if (data) { data.number = 16 // 處理後再發回domain1 window.parent.postMessage(JSON.stringify(data), 'http://www.domain1.com') } },false) </script>
總結前端性能優化的方法
幾種常見的JS遞歸算法
搭建一個vue-cli的移動端H5開發模板
封裝一個toast和dialog組件併發布到npm
從零開始構建一個webpack項目
總結幾個webpack打包優化的方法
一文讀盡前端路由、後端路由、單頁面應用、多頁面應用
關於幾個移動端軟鍵盤的坑及其解決方案
淺談JavaScript的防抖與節流