Ajax 跨域请求-- Cross Domain

本文涉及的产品
.cn 域名,1个 12个月
简介:

在认识 跨域 之前,先简单了解下域名和协议名,比如下面这个 URL


http://mail.163.com/index.html


http://              协议名,也就是HTTP超文本传输协议

mail                  服务器名

163.com           域名

mail.163.com    网站名

/                        根目录

index.html         根目录下的默认网页


1、什么是跨域请求?

请求的下一个资源所在的 协议域名端口号 三者之一与当前资源不一致就称为 跨域请求


简单理解,就是 $.get(url, [data], [callback], [type]) 里面的 url 的协议名、域名 或者 端口号与当前域名不一样

wKioL1g5N-zTVqHEAAEcMLjJtAQ988.png


为了避免晦涩难懂的文字,我们直接上一个小 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
30
31
32
<!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 = "//cdn.bootcss.com/jquery/3.1.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('http://dapengtalk.blog.51cto.com/',function(){
             console.log('btn2被单击后发起的XHR请求');
             console.log(obj);
         })
     })
 
</ script >
</ body >
</ html >


在浏览器地址栏输入“http://localhost:8081/Ajax/cross.html”打开页面,点击“非跨域按钮”,查看控制台

wKioL1g5ONjhojfSAABrX20sP0s236.png


点击“跨域按钮”,查看控制台,发现 XHR请求失败了,很明显,请求的域名不同,这就是典型的跨域

wKiom1g5OaqQdgXYAABl8WynHKU160.png


查看 Network,XHR请求发起了,而且状态码是200

wKioL1g-djjiAGNzAAB3zjIyH_Y018.png


查看请求头部消息,显示有 24 字节的响应消息

wKiom1g-dvvCoIIdAAEMLEZQztc590.png


查看响应消息,却显示“这个请求没有可用的响应消息”

wKiom1g-d0WyCfZCAAA-hkDOirs749.png





2、浏览器允许 跨域请求吗?


允许:<img src="跨域的图片">

允许:<link rel="stylesheet" href="跨域的CSS">

允许:<a href="跨域的链接">

允许:<script src="跨域的JS">

禁止AJAX请求是不允许跨域的!


说明:出于安全考虑,所有的浏览器默认都禁止使用XHR异步的跨域请求。


举个例子,比如上面提到的 img 允许跨域


1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE html>
< html >
< head  lang = "en" >
     < meta  charset = "UTF-8" >
     < title ></ title >
</ head >
< body >
 
< img  src = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"  alt = "百度logo" >
 
</ body >
</ html >


wKioL1g5PJuTQJtAAADSp6mQS7I031.png


不同协议名、不同域名,网页正常显示图片,说明允许跨域。但是文章一开始的 demo 中,使用 Ajax 发起异步请求的时候,却是不被允许的。那该怎么办呢?


3、跨域 解决方案


3-1、设置“Access-Control-Allow-Origin”头部


还记得吗?域名和域名对应的ip 也是不允许跨域的,在此基础上,我们把上面的例子稍作修改:

(尽管是同一个 2.php 页面,但一个是域名,一个是域名对应的ip)


HTML代码:

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
30
31
32
<!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 = "//cdn.bootcss.com/jquery/3.1.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('http://127.0.0.1:8081/Ajax/2.php',function(){
             console.log('btn2被单击后发起的XHR请求');
             console.log(obj);
         })
     })
 
</ script >
</ body >
</ html >


PHP代码:

1
2
3
4
5
6
7
<?php
header( 'Content-Type: application/json; charset=utf8' );
 
 
$data  = [ 'uname' => 'Tom' , 'age' =>20];
 
echo  json_encode( $data );


点击“非跨域按钮“,可以正常发起 Ajax 请求

wKiom1g5RI6Bg1jdAABrX20sP0s426.png

点击“跨域按钮”,报错了,说明这个属于 跨域

wKioL1g5RRyBQ_HWAAChFAkCKSg589.png

按照控制台给出的提示,我们在 php 页面中设置 Access-Control-Allow-Origin 头部


PHP代码:

1
2
3
4
5
6
7
8
9
10
<?php
header( 'Content-Type: application/json; charset=utf8' );
 
// 指定允许其他域名访问  
header( 'Access-Control-Allow-Origin:*' );  
 
 
$data  = [ 'uname' => 'Tom' , 'age' =>20];
 
echo  json_encode( $data );


看到 btn2,真是太难得了,这个也就说明 设置 Access-Control-Allow-Origin 头部 是可以解决跨域的

wKiom1g5RfjgHoixAACdP89SQC4466.png



3-2、使用 JSONP

基于3-1的示例代码,我们再来看一个例子:


HTML代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
< html >
< head  lang = "en" >
     < meta  charset = "UTF-8" >
     < title ></ title >
</ head >
< body >
< button  id = "crossBtn" >跨域按钮</ button >
 
< script  src = "//cdn.bootcss.com/jquery/3.1.1/jquery.js" ></ script >
< script >
     function doResponse(obj){
         alert(obj.uname+obj.age);
     }
 
     $('#crossBtn').click(function(){
         $.ajax({
             url:'http://127.0.0.1:8081/Ajax/3.php',
             success:doResponse
         })
     })
</ script >
</ body >
</ html >


PHP代码:

1
2
3
4
5
6
7
8
<?php
header( 'Content-Type: application/json' );
 
$data  = [ 'uname' => 'Tom' , 'age' =>20];
 
$json  =  json_encode( $data );   //返回一个json{"":"","":20}'
 
echo  'doResponse(' . $json . ')' ;



通过浏览器输入“http://localhost:8081/Ajax/jsonp01.html”打开网页,这是一个典型的跨域请求,这里可以使用JSONP手段来解决

wKioL1g87B7iUag2AABIGJ22xlY820.png


在$.ajax 方法中有一个 dataType属性,如果将该属性设置成 dataType:"jsonp",就能实现跨域


把上面的代码稍作修改:

HTML代码:

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
<!DOCTYPE html>
< html >
< head  lang = "en" >
     < meta  charset = "UTF-8" >
     < title ></ title >
</ head >
< body >
< button  id = "crossBtn" >跨域按钮</ button >
 
< script  src = "//cdn.bootcss.com/jquery/3.1.1/jquery.js" ></ script >
< script >
     function doResponse(obj){
         alert(obj.uname+obj.age);
     }
 
     $('#crossBtn').click(function(){
         $.ajax({
             url:'http://127.0.0.1:8081/Ajax/3.php',
             dataType:'jsonp',
             success:doResponse
         })
     })
</ script >
</ body >
</ html >


PHP代码:

1
2
3
4
5
6
7
8
<?php
header( 'Content-Type: application/javascript' );
 
$data  = [ 'uname' => 'Tom' , 'age' =>20];
 
$json  =  json_encode( $data );   //'{"":"","":20}'
 
echo  'doResponse(' . $json . ')' ;


重新打开页面,可以拿到数据了

wKioL1g87Hih5M6tAABYDfwTYIU743.png

如果想更深入的了解 JSONP 原理,可以查看另一篇文章 《详解 JSON 和 JSONP》

http://dapengtalk.blog.51cto.com/11549574/1877684


本文转自   frwupeng517   51CTO博客,原文链接:http://blog.51cto.com/dapengtalk/1876874
相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
7月前
|
JSON 前端开发 JavaScript
axios请求成功而$.ajax却不行排错
axios请求成功而$.ajax却不行排错
61 2
|
7月前
|
前端开发
解决前端ajax跨域请求不携带cookie信息JSESSIONID的问题
解决前端ajax跨域请求不携带cookie信息JSESSIONID的问题
|
22天前
|
XML 前端开发 JavaScript
|
2月前
|
JSON JavaScript 前端开发
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
《进阶篇第6章:vue中的ajax》包括回顾发送ajax请求方式、vue-cli脚手架配置代理服务器、vue-resource
59 22
|
2月前
|
前端开发 JavaScript
回顾前端页面发送ajax请求方式
回顾前端页面发送ajax请求方式
38 18
|
2月前
|
前端开发 JavaScript Java
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
第6章:Vue中的ajax(包含:回顾发送ajax请求方式、vue-cli脚手架配置代理服务器)
73 4
|
2月前
|
前端开发 JavaScript 数据处理
JQuery 拦截请求 | Ajax 请求拦截
【10月更文挑战第4天】
95 1
|
3月前
|
前端开发
React技术栈-react使用的Ajax请求库实战案例
这篇文章介绍了在React应用中使用Axios和Fetch库进行Ajax请求的实战案例,展示了如何通过这些库发送GET和POST请求,并处理响应和错误。
59 10
React技术栈-react使用的Ajax请求库实战案例
|
3月前
|
前端开发
React技术栈-react使用的Ajax请求库用户搜索案例
这篇文章展示了一个React技术栈中使用Ajax请求库(如axios)进行用户搜索的实战案例,包括React组件的结构、状态管理以及如何通过Ajax请求获取并展示GitHub用户数据。
33 7
React技术栈-react使用的Ajax请求库用户搜索案例
|
3月前
|
JSON JavaScript 前端开发
Jquery常用操作汇总,dom操作,ajax请求
本文汇总了jQuery的一些常用操作,包括DOM元素的选择、添加、移除,表单操作,以及如何使用jQuery发送Ajax请求,涵盖了GET、POST请求和文件上传等常见场景。