本菜鸡最近在写某个页面请求数据时,报了如下的错误。

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玩玩

简单聊聊跨域

要了解跨域,必须先了解浏览器同源策略,接下来搬运了一些大神的总结

什么是同源策略?

同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

同源策略限制以下几种行为:

1.Cookie、LocalStorage 和 IndexDB 无法读取
2.DOM 和 Js对象无法获得
3.AJAX 请求不能发送

假设没有同源策略,那么我在A网站下的cookie就可以被任何一个网站拿到;那么这个网站的所有者,就可以使用我的cookie(也就是我的身份)在A网站下进行操作。同源策略可以算是 web 前端安全的基石,如果缺少同源策略,浏览器也就没有了安全性可言。

同源策略做了很严格的限制,但是在实际的场景中,又确实有很多地方需要突破同源策略的限制,也就是我们常说的跨域。
跨域的方法有很多(如接下来要玩的jsonp跨域,还有cors跨域资源共享,反向代理等等)。

使用jsonp跨域

由于同源策略,一般来说位于 server1.example.com 的网页无法与不是 server1.example.com的服务器沟通,而HTML的<script> 元素是一个例外。利用<script>元素的这个开放策略,网页可以得到从其他来源动态产生的 JSON资料,而这种使用模式就是所谓的 JSONP。用 JSONP 抓到的资料并不是 JSON,而是任意的JavaScript,用 JavaScript 直译器执行而不是用 JSON 解析器解析。

示例代码

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

参考文章:

  1. 前端常见跨域解决方案(全)
  2. JSONP和CORS实现跨源请求
  3. 再也不学AJAX了!(三)跨域获取资源 ② - JSONP & CORS
  4. jsonp跨域请求详解——从繁至简

jsonp跨域获取数据实现百度搜索的更多相关文章

  1. jsonp跨域获取数据小解

    jsonp跨域获取数据小解 由于浏览器有同源策略,所以要想获取非同源(协议,域名,端口三者有一不同都算非同源)的页面的数据,就得进行跨域 (1) jsonp原理 由于script标签的src属性可以访 ...

  2. asp.net MVC jsonp跨域获取数据

    public class JsonpResult : JsonResult { object _data = null; public JsonpResult() { } public JsonpRe ...

  3. 利用location.hash+iframe跨域获取数据详解

    前言 如果看懂了前文利用window.name+iframe跨域获取数据,那么此文也就很好理解了.一样都是动态插入一个iframe,然后把iframe的src指向服务端地址,而服务端同样都是输出一段j ...

  4. jQuery之ajax的跨域获取数据

    如果获取的数据文件存放在远程服务器上(域名不同,也就是跨域获取数据),则需要使用jsonp类型.使用这种类型的话,会创建一个查询字符串参数 callback=? ,这个参数会加在请求的URL后面.服务 ...

  5. 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  6. XMLHTTPRequest对象不能跨域获取数据?!

    写了一小段代码,是用XMLHTTPRequest对象来获取数据的,在本地服务器中,运行的很顺利,但是转向实际服务器(实质上就是转向http://gumball.wickedlysmart.com获取一 ...

  7. iframe 跨域问题解决方案 利用window.name+iframe跨域获取数据详解

    详解 前文提到用jsonp的方式来跨域获取数据,本文为大家介绍下如何利用window.name+iframe跨域获取数据. 首先我们要简单了解下window.name和iframe的相关知识.ifra ...

  8. 使用JSONP跨域请求数据

    下面代码,可以使用JSONP进行跨域请求数据,Insus.NET记录以下,以备忘记.

  9. 各大搜索引擎智能提示API(JSONP跨域实现自动补全搜索建议)

    ---------------------------------------搜索引擎JSONP接口--------------------------------------------- 提示:U ...

随机推荐

  1. [CSP-S模拟测试94]题解

    A.凉宫春日的忧郁 高精硬上似乎跑不过,其实可以都取个$log$.那么只需要比较$y\times log ^x$和$\sum \limits _{i=1}^y log^i$就好了. #include& ...

  2. 前端面试之路之HTML面试真题

    1.doctype的意义是什么 让浏览器以标准模式渲染 让浏览器知道元素的合法性 2.HTML XHTML HTML5的关系 HTML属于SGML XHTML属于XML,是HTML进行XML严格化的结 ...

  3. (转)原理到实现 | K8S 存储之 NFS

    转:https://mp.weixin.qq.com/s/Mrr1Rnl_594Gyyn9fHekjw 1NFS介绍 NFS是Network File System的简写,即网络文件系统,NFS是Fr ...

  4. 【easyui-combobox】下拉菜单自动补全功能,Ajax获取远程数据源

    这个是针对easyUI的下拉菜单使用的,Ajax获取远程数据源 HTML 页面 <input id="uname" name="uname" class= ...

  5. php面试专题---10、网络协议考点

    php面试专题---10.网络协议考点 一.总结 一句话总结: 网络的考点其实就是这些:常见状态码,常见协议,osi七层模型,http和https 1.HTTP/1.1中,状态码200.301.304 ...

  6. php.ini 配置项详解

    本文主要对php.ini文件进行详细的解释 engine = On ——> 在apache下启用php语言引擎 short_open_tag = Off ——> 是否开启段标签  若php ...

  7. p4899 [IOI2018] werewolf 狼人

    分析 我用的主席树维护qwq 代码 #include<iostream> #include<cstdio> #include<cstring> #include&l ...

  8. P1983车站分级

    %%%rqy 传送 我们注意到题目中这段话: 既然大于等于x的站都要停,那么不停的站的级别是不是都小于x?(这里讨论在始发站和终点站以内的站(注意这里是个坑)) 我们可以找出每趟车没停的站,向所有停了 ...

  9. Linux 中设置进程通过 systemctl 启动

    对于某些脚本或需要启动命令的程序,可以通过创建 xx.service 服务文件来使用 systemctl 控制. 例如,对于 docker-compose,其后台启动且忽略输出信息的命令为: $ no ...

  10. Netty核心组件介绍及手写简易版Tomcat

    Netty是什么: 异步事件驱动框架,用于快速开发高i性能服务端和客户端 封装了JDK底层BIO和NIO模型,提供高度可用的API 自带编码解码器解决拆包粘包问题,用户只用关心业务逻辑 精心设计的Re ...