1.什么是同源策略
同源策略 同源策略是一种为浏览器安全考虑而出台的一种策略,它可以保证用户信息安全,防止恶意的网站窃取。 最初的同源政策是指A网站在客户端设置的Cookie,B网站是不能访问的。随着互联网的发展,同源政策也越来越严格,在不同源的情况下,其中有一项规定就是无法向非同源地址发送Ajax请求,如果请求,浏览器就会报错。 同源指的是:(1)同协议 (2)同域名 (3)同端口 跨域 由于同源策略的影响,当我们从一个域名的网页去请求另一个域名的资源时,就无法成功获取资源。如果我们想要成功获取资源,那么就要用到跨域。
2.如何解决跨域问题
1)JSONP
JSONP 的本质是,利用script标签 的src属性不受同源策略的影响,通过带有参数 和回调函数 的url 发起一次get请求(这也是jsonp只能发起get请求的原因,因为只有get请求才能把参数和回调函数拼接到url中),服务器将接口返回的数据拼凑到回调函数中 ,返回给浏览器,浏览器解析执行,从而前端拿到回调函数返回的数据 。 前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>jsonp跨域</title>
</head>
<body>
<script>
function fn(data) {
console.log('客户端的fn函数被调用了')
console.log(data)
}
</script>
<script src="http://localhost:3001/test?name=admin&callback=fn"></script>
</body>
</html>
后端代码(node):
const express = require('express');
const app = express();
app.get('/test',(req,res) => {
var result = 'fn({name:"张三"})'
res.send(result)
})
app.listen(3001)
console.log('端口为3001的服务器启动成功!')
2)CORS
(1)CORS的定义
跨域资源共享(Cross Origin Resource Sharing, CORS)是一种机制,它使用额外的HTTP头来告诉浏览器,让运行在一个origin(domain)上的Web应用被准许访问来自不同源服务器上的指定资源。当一个资源从该资源本身所在的服务器不同的域,协议或端口请求一个资源时,资源会发起一个跨域HTTP请求。实现CORS的关键是服务器,只要服务器实现了CORS请求,就可以跨源通信了。
CORS的实现方式 很简单,当使用XMLHttpRequest 发送请求时,浏览器发现该请求不符合不符合同源策略,会给该请求加一个请求头:Origin ,后台进行一系列处理,如果确定接收请求则在返回结果中加入一个响应头:Access-Control-Allow-Origin ;浏览器判断响应头中是否包含Origin 的值,如果有则浏览器会处理响应,我们就可以拿到响应数据,如果不包含浏览器直接驳回,这时我们无法拿到响应数据。所以CORS 的表象是让你觉得它与同源的ajax请求 没啥区别,代码完全一样。
(2)简单请求和非简单请求
- 请求头为以下三种方法之一:
HEAD , GET , POST - HTTP的头信息不超过以下几个字段:
Accept ,Accept-Language ,Content-Language ,Last-Event-ID , Content-type :只限于三个值application/x-www-form-urlencoded , multipart/form-data , text/plain
(3)CORS简单请求过程
对于简单请求,浏览器会直接发出CORS请求,它会在请求的头部信息中增加一个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
如果Origin指定的域名不在许可范围之内,服务器会返回一个正常的HTTP 响应,浏览器发现没有上面的Access-Control-Allow-Origin ,浏览器就不会执行响应的内容。这个错误无法通过状态码识别,因为返回的状态码可能是200。 在简单请求中,在服务器内,至少需要设置字段:Access-Control-Allow 在这里插入代码片-Origin
(4)CORS非简单请求过程
非简单请求是对服务器有特殊要求的请求,比如请求方法为DELETE或者PUT等。非简单请求的CORS请求会在正式通信之间进行一次HTTP查询请求,称为预检请求 。
浏览器会询问服务器,当前所在的网页是否在服务器的允许范围之内 ,以及可以使用哪些HTTP请求方式 和头信息字段 ,只有得到肯定回复,才会进行正式的HTTP请求,否则报错。
预检测请求使用的请求方法是OPTIONS,表示这个请求是来询问的,它的请求头中的关键字段是Origin,表示来自哪个源。除此之外,头部信息还包括两个字段:
Access-Control-Request-Method
Access-Control-Request-Headers
服务器在收到浏览器的预检请求之后,会根据头信息的三个字段来进行判断,如果在返回的头信息中有Access-Control-Allow-Origin这个字段就会允许跨域,如果没有,就是不同意这个预检请求,就会报错。服务器回应的cors字段如下:
Access-Control-Allow-Origin:http://api.bob.com
Access-Control-Allow-Methods:GET,POST,PUT
Access-Control-Allow-Headers:X-Custom-Header
Access-Control-Allow-Credentials:true
Access-Control-Max-Age:10000
只要服务器通过了预检请求,在以后每次的CORS请求都会自带一个Origin头信息字段。服务器的响应,也都会有一个Access-Control-Allow-Origin 头信息字段。 在非简单请求中,至少要设置以下字段:
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
减少OPTIONS请求次数 : OPTIONS请求 次数过多机会损耗页面加载的性能,降低用户体验度。所以尽量要减少OPTIONS请求 次数,可以后端在请求的返回头部添加:Access-Control-Max-Age: number 。它表示预检请求的返回结果可以被缓存多久,单位是秒。这字段值对完全一样的URL的缓存设置生效,所以设置了缓存时间,在这个时间范围内,再次发送请求就不需要进行预检请求了。
3)nginx代理跨域
niginx反向代理接口跨域 跨域问题:同源策略仅是针对浏览器的安全策略。服务器端调用HTTP接口只是使用HTTP协议,不需要同源策略,也就不存在跨域问题。 实现思路:通过Nginx配置一个代理服务器域名与domain1相同,端口不同做跳板机,反向代理访问domain2接口,并且顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域访问。 nginx.conf 具体配置:
#proxy服务器
server {
listen 81;
server_name www.domain1.com
location / {
#反向代理
proxy_pass http://www.domain2.com:8080;
#修改cookie里域名
proxy_cookie_domain www.domain2.com www.domain1.com;
index index.html index.htm;
# 当用webpack-dev-server等中间件代理接口访问nginx时
# 此时无浏览器参与,故没有同源限制,下面的跨域配置不可启用
# 当前端只跨域不带cookie时,可为*
add_header Access-Control-Allow-Origin http://www.domain1.com
add_header Access-Control-Allow-Credentials true;
}
}
3.正向代理和反向代理的区别
正向代理 : 客户端想要获得一个服务器的数据,但是因为种种原因无法直接获取。于是客户端设置了一个代理服务器,并且指向目标服务器,之后代理服务器像目标服务器转交请求并将获得的内容发送给客户端。这样本质上起到了对真实服务器隐藏真实客户端的目的。实现正向代理需要修改客户端,比如浏览器的配置。 反向代理 : 服务器为了能够将工作负载分布到多个服务器来提高网站性能(负载均衡)等目的,当其受到请求后,会首先根据转发规则来确定请求应该被转发到哪个服务器,然后将请求转发到对应的真实服务器上。这样本质起到了对客户端隐藏真实服务器的作用。 一般使用反向代理后,需要通过修改DNS让域名解析到代理服务器IP,这时浏览器无法察觉到真正服务器的存在,当然也就不需要修改配置了。 正向代理和反向代理的结构 : 正向代理和反向代理的结构是一样的,都是client-proxy-server 的结构,它们主要的区别就在于中间这个proxy 是哪一方设置的。在正向代理中,proxy 是client 设置的,用来隐藏client ;而在反向代理中,proxy 是server 设置的,用来隐藏server .
4.NginX的概念及其工作原理
NginX 是一款轻量级的Web服务器 ,也可以用于反向代理 ,负载均衡 和HTTP缓存 等。NginX使用异步事件驱动的方法来处理请求,是一款面向性能设计的HTTP服务器。 传统的Web服务器 如Apache 是process-based 模型的,而Nginx 是基于event-driven 模型的。正是这个主要的区别带给了Nginx 在性能上的优势。 Nginx架构 的最顶层是一个master process ,这个master process 用于生产其他的worker process ,这一点和Apache 非常像,但是Nginx 的worker process 可以同时处理大量的HTTP请求,而每个Apache process 只能处理一个。
|