摘要:把数据包裹在一个客户端声明的本地的回调函数中,这样可以动态加载一个跨域服务器数据。在本地声明这个动态中的回调函数名称,并且定义该函数,然后通过参数传递到服务器。
为什么要跨域
我们都知道在浏览器地址栏输入地址的时候可以随便访问一个页面,但是如果你在ajax请求中发出一个xhr请求那么因为浏览器安全策略只有同源的服务器才能处理。这就是同源策略 要求协议/域名/端口三者完全一致才能访问
例如以下的代码例子,我们需要获取服务器上README.md里面的数据
{ status:"sucess", data:{ city:["南京","北京"] } }
本地js代码如下
如果地址栏是下面这样
那么我们是可以访问到这个数据文件的
如果我在另外一个不同源域名下执行同样的代码例如下面这个地址
那么就会出现下面的错误
这个错误的意思说白了就是服务器禁止不同源的页面进行ajax请求数据。
非要获取这个数据我们应该怎么做我们注意到有的网站会提供cdn服务我们可以从不同的服务器添加下面的代码
这就为我们跨域获取数据提供了可能
var path = require("path") var express = require("express") const app = express() app.use(express.static(path.join(__dirname, "jsonp"))) console.log("> Starting dev server...") app.get("/detail", (req, res) => { let cb = req.query.cb ? req.query.cb : null // console.log("succuess") let readStream = fs.createReadStream(`README.md`) let data = "" readStream.on("data", chunk => { data += chunk }) readStream.on("end", () => { // console.log(data) res.send(`${cb}(${data})`) }) }) var server = app.listen(8888) console.log("server is running at port 8888")
1.基本原理我们可以动态生成script标签,把请求的url添加到script标签的src属性上。把数据包裹在一个客户端声明的本地的回调函数中,这样可以动态加载一个跨域服务器数据。
function jsonp(obj) { let scriptDOM = document.createElement("script") scriptDOM.setAttribute("src", `${obj.url}?cb=${obj.cb}`) window["callback"] = obj.success document.querySelector("body").appendChild(scriptDOM) scriptDOM.onload = function() { window["callback"] = null this.parentNode.removeChild(this) } scriptDOM.onerror = e => { console.log("jsonp error!", e) } } jsonp({ url: "http://localhost:8888/detail", cb: "callback", success: data => { if (data) { console.log("jsonp data", data) } } })
2.在本地声明这个动态script中的回调函数名称,并且定义该函数,然后通过url参数传递到服务器。服务器把数据包裹成这个函数的参数传递回来,跨域就实现了。
为什么要这么做?以前我也很困惑。你获取到的数据有可能是个json也有可能是个纯文本,而script标签内的内容只能是合法的js语句,如果你没有用回调函数包裹,直接从服务器传递回来原生数据。有可能是一段恶意代码,或者是非法的js字符,那么浏览器就会报错或者产生不可预料的显示结果。并且你事先不知道浏览器传递过来的代码跟你写的有没有冲突,是不是完全耦合。只有在本地定义一个函数传递到服务器,这样服务器用该函数包裹代码后传递回来才能跟我们的本地js代码紧密配合。这样服务器传递回来执行的代码就是我们自己定义的函数(数据存在函数的参数里),可以很好跟我们自己的代码配合。这样颇有Vue Angular子组件向父组件传递数据的思想
这样不同域名下的数据我们拿到了结果如下
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/82767.html
摘要:更新了个版本,最新正式版是语言的下一代标准,早已在年月正式发布。基本不支持移动端浏览器对的支持情况版起便可以支持的新特性。比较通用的工具方案有,,,等。 1、ECMAScript是什么? 和 JavaScript 有着怎样的关系? 1996 年 11 月,Netscape 创造了javascript并将其提交给了标准化组织 ECMA,次年,ECMA 发布 262 号标准文件(ECMA-...
摘要:协程的历史说来话长,要从生成器开始讲起。我们可以使用把数据发送给协程函数。可以看到,在第次接收完数据之后,会产生结束的异常,因为程序流程结束了,这是正常现象。在这个阶段,协程本质上还是由生成器构成的。所以,协程的介绍到这里就结束啦。 在上一篇对python并发编程的理解 中,我简单提到了协程的概念,有一个错误需要指出的是,asyncio不全是对协程的实现,只是用到了协程。 协程的历史说...
摘要:通过监视资源的变化,并根据的信息生成记录写入到中。是唯一保留的容器,依然提供健康检查。操作会获取最新的全量资源与本地状态进行比较来产生通知,可以避免网络原因导致的丢失通知的情况。最后一个参数用来设置处理事件的回调。 上一期我们以1.2版本为背景,介绍了K8S的服务发现和kube-dns插件的相关内容。有了上一期内容作为基础,这期了解最新版本的kube-dns就会容易很多。 本文主要对比...
摘要:前言我是,如果你还不认识我,不妨先看看技术的前世今生一平静的生活已经有一段日子了。传送门技术的前世今生一技术的前世今生三 前言:我是JavaScript,如果你还不认识我,不妨先看看《Web技术的前世今生(一)》 平静的生活已经有一段日子了。 这一天,HTML大哥面露不悦地走过来问我: Js,你是打算和我们分家吗? 大哥,您这说的哪里话,我什么地方做的不对么?我一脸茫然地回答道。 哼,...
阅读 1179·2021-11-24 11:16
阅读 3412·2021-11-15 11:38
阅读 1889·2021-10-20 13:47
阅读 530·2021-09-29 09:35
阅读 2165·2021-09-22 15:17
阅读 991·2021-09-07 09:59
阅读 3353·2019-08-30 13:21
阅读 2885·2019-08-30 12:47