跨域(由浏览器同源策略限制的一类请求场景)
定义
当一个请求url的协议
、域名
、端口
三者之间任意一个与当前页面url不同即为跨域
同源策略限制以下几种行为:
1. Cookie、LocalStorage 和 IndexDB 无法读取
2. DOM 和 Js对象无法获得
3. AJAX 请求不能发送
解决方法:
1. 通过JSONP(jsonp缺点:只能实现get一种请求)
比如下面的例子利用script标签加回调函数
可以在
<script>
function f(data){
alert(data)
}
</script>
<script src="http://localhost:8000?callback=f"></script>
var app2 = express();
app2.get("/",function(req,res){
var funcname = req.query.callback;
res.send(funcname+"('messgae')")
})
app2.listen(8000)
2. 跨域资源共享(CORS)
浏览器将CORS请求分成两类:简单请求
(simple request)和非简单请求
(not-so-simple request)。
简单请求
只要同时满足以下两大条件,就属于简单请求
。
(1) 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
(2)HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值
- application/x-www-form-urlencoded、中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
- multipart/form-data、需要在表单中进行文件上传时,就需要使用该格式
- text/plain 纯文本格式
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段
。
Origin字段
用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。
//该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段。
Access-Control-Allow-Credentials: true
另一方面,开发者必须在AJAX请求中打开withCredentials
属性。
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
下面是一个修改案例
//比如在express后端 直接修改响应头!!!
var app2 = express();
app2.get("/",function(req,res){
res.header("Access-Control-Allow-Origin","*")
res.send("message")
})
app2.listen(8000)
非简单请求
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT
或DELETE
,或者Content-Type
字段的类型是application/json
。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"
请求(preflight)。
浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
CORS与JSONP的使用目的相同,但是比JSONP更强大。
www.bilibili.com/video/BV1Kt…
阮一峰 跨域资源共享 CORS 详解
其他解决跨域方法:
- document.domain + iframe跨域
- location.hash + iframe
- window.name + iframe跨域
- postMessage跨域
- nginx代理跨域
- nodejs中间件代理跨域
- WebSocket协议跨域
见相关文章: segmentfault.com/a/119000001…
后期再补
其他阅读学习[ajax,fetch,axios]
ajax
$.ajax({
url: "test.html",
context: document.body
}).done(function() {
$( this ).addClass( "done" );
});
api.jquery.com/jquery.ajax…
fetch
//使用案例 提交表单
const form = document.querySelector('form');
const response = await fetch('/users', {
method: 'POST',
body: new FormData(form)
})
阮一峰 Fetch API教程
axios
//使用案例 发送 POST 请求
axios({
method: 'post',
url: '/user/12345',
headers:{'content-type':"application/x-www-form-urlencoded"},
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
}).then(res=>{console.log(res.data)});
使用说明 · Axios 中文说明
axios中文网
www.bilibili.com/video/BV14t…
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!