本菜雞最近在寫某個頁面請求數據時,報了以下的錯誤。html
Failed to load https://...:
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin ' http://127.0.0.1:7070' is therefore not allowed access.
瞭解緣由後,得知是因爲跨域請求致使的,學習了一下跨域及同源策略相關知識後,寫了個demo玩玩前端
要了解跨域,必須先了解瀏覽器同源策略,接下來搬運了一些大神的總結git
同源策略/SOP(Same origin policy)是一種約定,由Netscape公司1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,若是缺乏了同源策略,瀏覽器很容易受到XSS、CSFR等攻擊。所謂同源是指"協議+域名+端口"三者相同,即使兩個不一樣的域名指向同一個ip地址,也非同源。github
同源策略限制如下幾種行爲:web
1.Cookie、LocalStorage 和 IndexDB 沒法讀取 2.DOM 和 Js對象沒法得到 3.AJAX 請求不能發送
假設沒有同源策略,那麼我在A網站下的cookie就能夠被任何一個網站拿到;那麼這個網站的全部者,就可使用個人cookie(也就是個人身份)在A網站下進行操做。同源策略能夠算是 web 前端安全的基石,若是缺乏同源策略,瀏覽器也就沒有了安全性可言。chrome
同源策略作了很嚴格的限制,可是在實際的場景中,又確實有不少地方須要突破同源策略的限制,也就是咱們常說的跨域。
跨域的方法有不少(如接下來要玩的jsonp跨域,還有cors跨域資源共享,反向代理等等)。json
因爲同源策略,通常來講位於 server1.example.com 的網頁沒法與不是 server1.example.com的服務器溝通,而HTML的<script>
元素是一個例外。利用<script>
元素的這個開放策略,網頁能夠獲得從其餘來源動態產生的 JSON資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並非 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。segmentfault
示例代碼跨域
function handleResponse(response) { alert(`You get the data : ${response}`) } const script = document.createElement('script') script.src = 'http://somesite.com/json/?callback=handleResponse' document.body.insertBefore(script, document.body.firstChild)
這裏的callback回調函數很重要,動態添加在body中的script標籤可使用被加載的文件與HTML文件下的其餘JS文件共享一個全局做用域。也就是說,<scritp>標籤加載到的資源是能夠被全局做用域下的函數所使用的!瀏覽器
百度有一個對外暴露的數據接口:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=1
在chrome瀏覽器中打開百度主頁,在開發者工具在 netkwork 能夠找到
咱們能夠直接拿來使用,配合jsonp就能實現跨域獲取輸入框內容相關熱點數據並點擊跳轉了,具體實現請看Github項目源碼
實現效果:
頁面結構很是簡單,如圖:
jsonp跨域實現代碼
document.onkeyup = function () { var val = text.value var script = document.createElement('script') script.src = `https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=${val}&cb=dosomething`; document.body.appendChild(script) } function dosomething (data) { var oUl = document.querySelector('#lists ul') oUl.innerHTML = '' data.s.map(function (html) { var oLi = document.createElement('li') oLi.innerHTML = html oLi.onclick = function () { window.location.href = `http://www.baidu.com/s?wd=${html}` } oUl.appendChild(oLi) }) }
僅僅是一個利用jsonp實現跨域的簡單小demo,便於和我同樣的新手學習,其它結構和樣式文件就不一一列出來了,能夠到我下載個人完整項目查看
完整項目地址:Github:baidu_demo
參考文章: