跨域
默认不同源地址之间不能发送请求, 只有同源的地址才可以相互通过 AJAX 的方式请求
什么是不同源
协议不同
或端口号不同
或域名不同
, 都叫不同源
跨域和 AJAX 没有关系
- 跨域是通过 script 标签发送请求
- AJAX 是通过 xhr 对象来发送请求
解决方案
- 现代化的 Web 应用中肯定会有不同源的现象,所以必然要解决这个问题,从而实现跨域请求
CORS
Cross Origin Resource Share 跨域资源共享
跨域资源共享(CORS) 是一种机制,它使用额外的 HTTP 头来告诉浏览器让运行在一个 origin (domain) 上的Web 应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域、协议或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。
跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。现代浏览器支持在 API 容器中(例如
XMLHttpRequest
或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源
只需要在后台中 设置响应头来允许跨域请求, 客户端无需作出变化 (依然通过 ajax 处理请求)
1
2// Node.js 作服务端
res.header('Access-Control-Allow-Origin', '*')1
2
3
4// php 作服务端
php
header('Access-Control-Allow-Origin: *')1
2
3
4// 客户端
$.get('http://locolhost/cors.php', {}, function (res) {
console.log(res)
})
JSONP
JSON with Padding,是一种 借助于 script 标签发送跨域请求
的技巧
原理
- 在客户端借助 script 标签请求服务端的一个地址,服务端返回一段带有函数调用的 JavaScript 函数调用的脚本,将原本需要返回给客户端的数据传递进去, 返回给客户端
为什么不用 img / a / link?
- img —— 可以发送请求, 但不能返回响应结果
- link —— 可以返回响应结果, 但是无法处理相应结果
以后绝大多数情况都是采用 JSONP 的手段完成不同源地址之间的跨域请求
1
2<!-- 客户端 -->
<script src="http://api.zce.me/users.php?callback=foo"></script>1
2// 服务端返回
foo(['我', '是', '你', '原', '本', '需', '要', '的', '数', '据'])总结
- 由于 XMLHttpRequest 无法发送不同源地址之间的跨域请求,所以我们必须要另寻他法,script 这种方案就是我们最终选择的方式,我们把这种方式称之为 JSONP
JSONP 的封装
1 | <script> |
JSONP 的问题
JSONP 需要服务端配合,服务端按照客户端的要求返回一段 JavaScript 调用客户端的函数的字符串
- 只能发送 GET 请求
- ⚠️ JSONP 用的是 script 标签,跟 AJAX 提供的 XMLHttpRequest 没有任何关系!!!
jQuery 中使用 JSONP
jQuery 中使用 JSONP 就是将 dataType 设置为 jsonp
1 | $.ajax({ |