什么是跨域
跨域:
浏览器对于javascript的同源策略的限制,例如a.cn下面的js不能调用b.cn中的js,对象或数据(因为a.cn和b.cn是不同域),所以跨域就出现了.
上面提到的,同域的概念又是什么呢??? 简单的解释就是相同域名,端口相同,协议相同
同源策略:
请求的url地址,必须与浏览器上的url地址处于同域上,也就是域名,端口,协议相同.
比如:我在本地上的域名是xxx.cn,请求另外一个域名一段数据
这个时候在浏览器上会报错:
1 | Failed to load http:/xxx.cn/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://sss.com' is therefore not allowed access. |
这个就是同源策略的保护,如果浏览器对javascript没有同源策略的保护,那么一些重要的机密网站将会很危险~
xxx.cn/json/jsonp/jsonp.html | ||
---|---|---|
请求地址 | 形式 | 结果 |
http://xxx.cn/test/a.html | 同一域名,不同文件夹 | 成功 |
http://xxx.cn/json/jsonp/jsonp.html | 同一域名,统一文件夹 | 成功 |
http://a.xxx.cn/json/jsonp/jsonp.html | 不同域名,文件路径相同 | 失败 |
http://xxx.cn:8080/json/jsonp/jsonp.html | 同一域名,不同端口 | 失败 |
https://xxx.cn/json/jsonp/jsonp.html | 同一域名,不同协议 | 失败 |
JS跨域
这里所说的JS跨域,指的是在处理跨域请求的过程中,技术面会偏浏览器端较多一些,一般是利用浏览器的一些特性进行hack处理,从而避开同源策略的限制。
JSONP
由于同源策略不会阻止动态脚本的插入到文档中去,所以催生出了一种很常用的跨域方式: JSONP(JSON with Padding)。
实例
创建三个文件
server.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14const http = require('http');
const fs = require('fs');
http.createServer(function (request,response) {
console.log('request come', request.url);
const html = fs.readFileSync('test.html','utf8');
// response.writeHead(200, {
// 'Content-Type': 'test/html'
// });
response.end(html);
}).listen(8888);
console.log ('server listening on http://localhost:8888');
server2.js
1
2
3
4
5
6
7
8
9const http = require('http');
http.createServer(function (request,response) {
console.log('request come', request.url);
}).listen(8887);
console.log ('server listening on http://localhost:8887');
test.html
1 | <!DOCTYPE html> |
同时启动 server.js
server2.js
服务
然后按照上面代码 使用 server.js
启动 test.html
页面 但是 test.htm
页面 发送一个http请求
请求的 服务器为端口8887
,也就是 server2.js
服务
此时页面上会提示 跨域1
Failed to load http://127.0.0.1:8887/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8888' is therefore not allowed access.
我们的解决方法就是
- 在server2.js 页面 http.createServer 的装添加一下页面
1
2
3
4response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
})
response.end('123');
上边的 'Access-Control-Allow-Origin': '*'
表示 允许跨域的 域名 ,*
表示 允许一切url的跨域 ,如果只是允许 某个网站访问数据 就可以直接 写网站域名
- 使用jsonp的方式解决跨域
在HTML添加标签1
<script src="http://localhost:8887"></script>
这样同样 可以请求到页面的数据
所以 jsonp 的实现原理, 就是 把请求的数据以标签请求资源的方式请求 ,浏览器对资源请求不会做限制 ,就可以请求到数据
CORS跨域限制以及预请求验证
cors 预请求
允许的方法 (method)
GET HEAD POST 不需要预请求验证
允许的 Content-Type
1 | text/plan |
以上是在form表单做element请求的时候 允许的类型
其他限制
请求头限制
网页 https://fetch.spec.whatwg.org/#cors-safelisted-request-header
xmlHttpRequestUpload 对象均没有注册任何时间监听器
请求中没有使用ReadableStream对象
如果以上都允许 服务区改为
1 | response.writeHead(200, { |
http报文格式
http方法
是用来定义对资源的操作
- get: 获取数据
- post: 创建数据
- put: 更新数据
- delete: 删除数据
最常用的事 post、get
http code
定义服务器队请求的处理结果
各个区间的code有个字的语义
- 200 - 299 代表这个操作成功的
- 300 - 399 代表这个操作重定向的,用别的方式获取这个数据
- 400 - 499 发送的请求有问题
- 500 - 599 服务器的错误
好的http服务可以通过 code直接判断结果
可缓存性
public
http请求返回过程中
private
no-cache
表示虽然可以缓存 ,但是下次请求还是要服务器验证
设置缓存时长
可以在加载一个js的时候 设置1
2'Content-Type':'text/javascript',
'Cache-Control': 'max-age=200, public',
这样的设置后 第二次加载页面时 如果在设置的事件内,会直接加载缓存中的文件
解决方法 就是在 js后边添加hash值 每次刷新都会改变hash值 所以就会重新加载页面