同源策略
同源指的是:协议相同、域名相同、端口相同。
不同源指的是:
- 域名不相同:完全跨域
- 域名相同,端口号不同:跨子域
1995 年同源策略由网景公司提出,目前各个浏览器都遵守;同源的目的是保护用户的信息安全。
如果为非同源,三种行为受到限制:
- Cookie、LoaclStorage、IndexDB 无法读取
- DOM 无法获得
- Ajax 请求不能发送
域名的概念
例如:www.baidu.com、www.jd.com,
它们的主域名相同,二级域名不同,存在跨域。
跨域的概念
完全跨域是指:例如 www.baidu.com
和 www.sogou.com
。
跨子域是指:例如 www.baidu.com
和 fy.baidu.com
为跨子域。
常见的跨域
在之前的学习中,有些 HTML 标签已经实现了跨域的访问功能。例如:
img
:标签可以在我们自己的 HTML 页面中引入其他网站的一些图片。link
:元素可以引入 CSS 文件script
:可以引入 JavaScript 文件iframe
:可以在本地 HTML 页面中
JSONP 实现跨域
JSONP 全称“JSON with Padding” 是 JSON 的一种使用模式。
利用 <script>
实现跨域访问
实现步骤:
- 定义
script
标签,标签的src
属性指向服务器的地址,地址后跟回调函数的名称; - 定义
script
标签,标签内声明函数,函数名为上面script
中的回调函数的名称,该函数有一个 data 形参用来接收服务器的响应数据 - 搭建一个自己的 sever。
- 自己的 sever 中需要调用回调函数,其参数中传入 json 格式的字符串
其实还是利用了 script
标签的开放性原则,将地址指向了另一个域。然后发送请求,获取响应数据。
sever.js 中代码如下所示:
const http = require("http");
const hostname = "127.0.0.1";
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
res.end('fun({"msg":"hello world!"})');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
第 9 行代码中,调用了本地 html 页面中 script 标签内的函数,其中传入参数为字符串形式的 json。
HTML
<body>
<script>
function fun(data){
console.log(data)
}
</script>
<script src="http://127.0.0.1:3000/?callback=fun"></script>
</body>
这里需要注意,要将定义有函数的 script 标签声明在,跨域 script 的前面,否则会抛出异常 fun is not function
当我们打开 html 页面,结果如下所示:
采用 script 跨域原理图:
$.getJSON()
实现跨域
使用 $.getJSON()
方法跨域时,callback回调函数要赋值为 ? ,jQuery 底层会自动生成函数名,
后跟匿名回调函数,回调函数中有一个形参为 data,其中为服务器的响应数据。
sever2.js
const http = require("http");
const hostname = "127.0.0.1";
const port = 3000;
const server = http.createServer((req, res) => {
var url = req.url;
var url_obj = require("url").parse(url);
var func_name = url_obj.query.split("&")[0].split("=")[1]
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain");
res.end(func_name+'({"msg":"hello world!"})');
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
HTML
<body>
<script src="../jQuery中的Ajax/jquery-1.12.4.js"></script>
<script>
$.getJSON('http://127.0.0.1:3000/?callback=?',function (data){
console.log(data)
})
</script>
</body>
结果: