1 | https://mail.google.com/mail/#inbox |
以上URL的构成:1
2
3
4
5
6http: 协议名,也就是HTTP超文本传输协议
mail 服务器名
google.com 域名
mail.google.com 网站名
/ 根目录
`#inbox` 根目录下的默认网页
1. 什么是跨域请求?
请求的资源所在的协议/域名/端口号
三者之一与当前资源不一致即为跨域请求。
关于Ajax环境的搭建先略过,直接来一段demo看:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<h2>非跨域请求</h2>
<button id="btn1">非跨域按钮</button>
<h2>跨域请求</h2>
<button id="btn2">跨域按钮</button>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js"></script>
<script>
$('#btn1').click(function(obj){
$.get('http://localhost:8081/Ajax/2.php',function(){
console.log('btn1被单击后发起的XHR请求');
console.log(obj);
})
})
$('#btn2').click(function(obj){
$.get('https://unsplash.com',function(){
console.log('btn2被单击后发起的XHR请求');
console.log(obj);
})
})
</script>
</body>
</html>
PHP代码:1
2
3
4<?php
header('Content-Type: application/json; charset=utf8');
$data = ['uname'=>'Tom','age'=>20];
echo json_encode($data);
在浏览器地址栏输入http://localhost:8081/Ajax/cross.html
打开页面。
点击’非跨域按钮’,查看控制台发现,请求是成功的,并且可以看见事件对象。
点击’跨域按钮’,查看控制台,发现XHR请求失败了,因为请求的域名不同。
2. 浏览器允许跨域请求吗?
允许:< img src="跨域的图片">
允许:<link rel="stylesheet" href="跨域的CSS">
允许:<a href="跨域的链接">
允许:<script src="跨域的JS">
禁止:AJAX请求不允许跨域
处于安全原因的考虑,所有的浏览器默认禁止使用XHR异步的跨域请求。
比如img图片跨域:
1 | < img src="https://images.unsplash.com/photo-1425342605259-25d80e320565?dpr=2&auto=format&fit=crop&w=1080&h=720&q=80&cs=tinysrgb&crop="> |
不同协议名、不同域名,网页正常显示图片,说明允许跨域。
图像跨域主要有两个缺点:1.只能发送get请求。2.无法访问服务器的响应文本所以,图像跨域只能用于浏览器与服务器间的单项通信。
##3. 跨域解决方案
1. 设置”Access-Control-Allow-Origin”头部
在PHP页面中设置Access-Control-Allow-Origin
头部信息
PHP代码:1
2
3
4
5
6
7<?php
header('Content-Type: application/json; charset=utf8');
// 指定允许其他域名访问
header('Access-Control-Allow-Origin:*');
$data = ['uname'=>'Tom','age'=>20];
echo json_encode($data);
在浏览器http://localhost:8081/Ajax/cross.html
页面中发现,跨域请求是成功的。
2. 使用JSONP
1 | <button id="crossBtn">跨域按钮</button> |
PHP代码:1
2
3
4
5
6
7
8
header('Content-Type: application/json');
$data = ['uname'=>'Tom','age'=>20];
$json = json_encode($data); //返回一个json{"":"","":20}'
echo 'doResponse('.$json.')';
在$.ajax 方法中有一个 dataType属性,如果将该属性设置成 dataType:”jsonp”,就能实现跨域
将$请求稍作修改:1
2
3
4
5
6
7$('#crossBtn').click(function(){
$.ajax({
url:'http://127.0.0.1:8081/Ajax/3.php',
dataType:'jsonp',
success:doResponse
})
})
再次打开页面查看,就可以获取到PHP文件中数据了。