前端开发中解决浏览器的跨域问题:
一、什么是跨域?
答:当前发起请求的域和该请求指向的资源所在的域不一致。具体表现在协议、域名、端口号——均一致为同域,有一个不同就是跨域。
--------------------------------------------------------------------------------------------------------------------------------
二、为什么要跨域?
答:①在前端开发中,经常需要到调用第三方服务接口;
②现在的项目大多采用前后端分离的模式,前端后端的域名不一致,因此需要解决跨域问题。
--------------------------------------------------------------------------------------------------------------------------------
三、解决“跨域”的五种常见方式:
注意:常见的html标签中的“img”、“script”、“form”、“link”、“iframe”标签发起请求时不存在跨域问题的限制。
1. JSONP
——根据“script”标签发送请求时不存在跨域问题,在“script”标签中发送相关请求
原理:①客户端在script标签中发送相关请求,并同时传递一个函数func;
②服务器端接收请求后,将准备好的数据data以“func(”+data+")"的形式发送给客户端
③客户端接收到“func(”+data+")"相关处理后,即执行函数func(data)
注意:由于JSONP基于script标签,因而只能处理get请求、无法处理post请求。
---------------------------------------------------------------------------------------------------------------
2. CORS跨域资源共享
与JSONP对比更有优势,无请求方式的局限性(post、get均可)。
客户端:与正常非跨域请求相同;
服务端:设置相关的请求header头部信息(注意需要处理options试探性请求)
---------------------------------------------------------------------------------------------------------------
3. http proxy代理跨域(利用Webpack配置):推荐使用。
优点:只需要在webpack.config.js文件中进行相关配置,无需其它编码,操作简单。
---------------------------------------------------------------------------------------------------------------
4. nginx反向代理
客户端发送的请求不是直接到达目的服务器,而是到达部署在目的服务器端的代理服务器,通过代理服务器转发接口请求,通过一定的转发规则将接口请求转发到目的服务器。
原理:
① 发送请求访问8081.max.com,通过本地host文件域名解析,找到192.168.72.49服务器(安装nginx)
② nginx反向代理接受客户端请求,找到server_name为8081.max.com的server节点,根据proxy_pass对应的http路径,将请求转发到端口号为8081的tomcat服务器。
前端发送请求时跟非跨域时一致,只需要在服务器端安装、配置nginx相关。
server {
listen 3000;
server_name localhost;
#将所有localhost:3000/为开头的请求转发
location / {
proxy_pass http://localhost:3001; //反向代理
index index.html index.htm;
#下面这两条配置,意思是将http头转发给后端以拿到客户端IP地址
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
另,为什么称作“反向代理”?
正向代理:代理服务器代理的是客户端。例如找一个代理服务器访问Google,客户端明确地指定要访问的目的服务器,而目的服务器并不知道客户端来源,在正向代理中客户端信息是被隐藏的。
反向代理:代理服务器代理的是目的服务器,代理服务器与目的服务器同属一个环境。发送请求的客户端是明确的,但请求具体由哪台服务器处理并不明确,且代理服务器对外透明,客户端并不知道自己访问的是代理服务器,在反向代理中服务端被隐藏。
---------------------------------------------------------------------------------------------------------------
5. postMessage——基于iframe标签
即window.postMessage() 方法,使用详情见:https://developer.mozilla.org/zh-CN/docs/Web/API/Window/postMessage
---------------------------------------------------------------------------------------------------------------
6. socket.io ——实时通信聊天
使用详情见:https://socket.io/get-started/chat