- 跨域:浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制。
- 同源策略:如果两个页面的协议,域名,端口都相同,则两个页面具有相同的源。
同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。这是一个用于隔离潜在恶意文件的重要安全机制。
不受同源策略限制的
- 页面中的链接,重定向以及表单提交是不会受到同源策略限制的。
- 跨域资源的引入是可以的。但是js不能读写加载的内容。如嵌入到页面中的等。
受到限制的
- Cookie、LocalStorage 和 IndexDB 无法读取
- DOM和JS对象无法获得
- AJAX 请求不能发送
- jsonp的核心原理就是:目标页面回调本地页面的方法,并带入参数
- 服务器端实现 JSONP 接口的步骤
- 服务器端获取客户端发送过来的query参数,其中参数有回调函数的名字
- 得到的数据,拼接出一个函数调用的字符串
- 把上一步拼接得到的字符串,响应给客户端的 标签进行解析执行
- jsonp的缺点:只能发送get一种请求。
1、原生JS实现
通过script标签src属性,发送带有callback参数的GET请求,服务端将接口返回数据拼凑到callback函数中,返回给浏览器,浏览器解析执行,从而前端拿到callback函数返回的数据。
后端nodejs代码
主要用来模拟服务器
携带参数必须是字符串
2、jquery Ajax实现
以jquery来发起jsonp请求
3、Vue axios实现
- CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
- 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
- CORS需要浏览器和服务器同时支持。
- 目前,所有主流浏览器都支持该功能,IE10以下不支持。
- 浏览器将CORS跨域请求分为:简单请求、非简单请求。
简单请求与非简单请求
简单请求
- 请求方式:get/post/head其中一种
- 请求头设置:
- Accept
- Accept-Language
- Content-Type:application/x-www-form-urlencoded、multipart/form-data、text/plain( 只限于三个值中的一个)
详细描述
对于简单请求,浏览器直接发出CORS请求。具体来说,就是在头信息之中,增加一个Origin字段。
举例:
- 发起请求
- 自动在头信息之中,添加一个Origin字段。
Origin:本次请求来自哪个域(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。
- 服务器判断此次请求Origin源
- 不在许可范围内:服务器会返回一个正常的 HTTP 回应。
- 浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被请求的异常回调函数捕获。
注意,这种错误无法通过状态码识别,因为 HTTP 回应的状态码有可能是200。
- 浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被请求的异常回调函数捕获。
- 在许可范围内:服务器返回的响应,会多出几个头信息字段。
- 有三个与 CORS 请求相关的字段,都以Access-Control-开头。
- 不在许可范围内:服务器会返回一个正常的 HTTP 回应。
- Access-Control解释
- Access-Control-Allow-Origin:必须的
它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。
- Access-Control-Allow-Credentials:可选
布尔值,表示是否允许发送 Cookie。默认情况下,Cookie 不包括在 CORS 请求之中(为了降低 CSRF 攻击的风险。)。设为true,即表示服务器明确许可,浏览器可以把 Cookie 包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送 Cookie,不发送该字段即可。
- Access-Control-Expose-Headers:可选
CORS 请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个服务器返回的基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。
- Access-Control-Allow-Origin:必须的
非简单请求
对服务器提出特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的类型是application/json。
预检请求
- 非简单请求的 CORS 请求,会在正式通信之前,增加一次 HTTP 查询请求,称为“预检”请求(preflight)。
- 浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些 HTTP 方法和头信息字段。
- 只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。
- 这是为了防止这些新增的请求,对传统的没有 CORS 支持的服务器形成压力,给服务器一个提前拒绝的机会,这样可以防止服务器收到大量DELETE和PUT请求,这些传统的表单不可能跨域发出的请求
举例
- 自动发出一个“预检”请求,要求服务器确认可以这样请求。下面是这个“预检”请求的 HTTP 头信息:
两个特殊字段:
- Access-Control-Request-Method必须的
- Access-Control-Request-Headers
服务器收到“预检”请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应
- Access-Control-Request-Method必须的
- 预检请求的回应:
服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。
HTTP回应中,除了关键的是Access-Control-Allow-Origin字段,其他CORS相关字段如下:
- Access-Control-Allow-Methods:必选
- Access-Control-Allow-Headers
- Access-Control-Allow-Credentials:可选
- Access-Control-Max-Age:可选
CORS跨域
1)前端设置
nodejs代码
在Express中通过第3方中间件来完成cors跨域解决
使用步骤分为如下 3 步:
- 运行 npm install cors 安装中间件
- 使用 const cors = require('cors') 导入中间件
- 在路由之前调用 app.use(cors()) 配置中间件
正向代理和反向代理
提到代理,肯定要说一下这两个的区别。
- 举个正向代理的例子
- 反向代理的例子
nginx配置解决iconfont跨域
浏览器跨域访问js、css、img等常规静态资源被同源策略许可,但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务器中加入以下配置。
nginx反向代理接口跨域
跨域问题:同源策略仅是针对浏览器的安全策略。服务器端调用HTTP接口只是使用HTTP协议,不需要同源策略,也就不存在跨域问题。
实现思路:通过Nginx配置一个代理服务器域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前域cookie写入,实现跨域访问。
nginx具体配置
node中间件实现跨域代理,原理大致与nginx相同,都是通过启一个代理服务器,实现数据的转发,也可以通过设置cookieDomainRewrite参数修改响应头中cookie中域名,实现当前域的cookie写入,方便接口登录认证。
1、nodejs服务器代理
使用node + express + http-proxy-middleware搭建一个proxy服务器。
npm i express htttp-proxy-middleware
2、vue框架的跨域
前提条件
这两个域名必须属于同一个一级域名!而且所用的协议,端口都要一致,否则无法利用document.domain进行跨域。
Javascript出于对安全性的考虑,而禁止两个或者多个不同域的页面进行互相操作。
而相同域的页面在相互操作的时候不会有任何问题。
举例
1)父窗口:(http://father.baidu.com/a.html)
hash 属性是一个可读可写的字符串,该字符串是 URL 的锚部分(从 # 号开始的部分)。
实现原理
- a想要与b跨域相互通信,通过中间页c来实现。
- 三个页面,不同域之间利用iframe的location.hash传值,相同域之间直接js访问来通信。
- 利用location.hash传值,创建定时器,坚持hash的变化,执行相应的操作。
下面我们来完成一个案例:
具体实现
- A域:a.html -> B域:b.html -> A域:c.html
- a与b不同域只能通过hash值单向通信,b与c也不同域也只能单向通信,但c与a同域,所以c可通过parent.parent访问a页面所有对象。
1)a.html:(http://www.baidu1.com/a.html)
2)b.html:(http://www.baidu2.com/b.html)
3)c.html:(http://www.baidu1.com/c.html)
优缺点
- location.hash + iframe跨域的优点:
- 可以解决域名完全不同的跨域
- 可以实现双向通讯
- location.hash + iframe跨域的缺点:
- location.hash会直接暴露在URL里,并且在一些浏览器里会产生历史记录,数据安全性不高也影响用户体验
- 另外由于URL大小的限制,支持传递的数据量也不大。
window.name属性的独特之处:只要在一个window下,无论url怎么变化,只要设置好了window.name,那么后续就一直都不会改变。同理,在iframe中,即使url在变化,iframe中的window.name也是一个固定的值,利用这个,我们就可以实现跨域了(2MB)。
举例
test1.html
test2.html
通过iframe的src属性由外域转向本地域,跨域数据即由iframe的window.name从外域传递到本地域。这个就巧妙地绕过了浏览器的跨域访问限制,但同时它又是安全操作。
PWA渐进式web应用
- 在HTML5中新增了postMessage方法,postMessage可以实现跨文档消息传输(Cross Document Messaging)
- 该方法可以通过绑定window的message事件来监听发送跨文档消息传输内容。
- 它可用于解决以下方面的问题:
- postMessage用法:
参数说明:
- data: html5规范支持任意基本类型或可复制的对象,但部分浏览器只支持字符串,所以传参时最好用JSON.stringify()序列化。
- origin: 协议+主机+端口号,也可以设置为"*",表示可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。
举例
- postMessage:发送
- onmessage:接收
1)a.html:(http://www.baidu1.com/a.html)
2)b.html:(http://www.baidu2.com/b.html)
- WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。
- 原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
WebSocket 如何工作
Web浏览器和服务器都必须实现 WebSockets 协议来建立和维护连接。由于 WebSockets 连接长期存在,与典型的HTTP连接不同,对服务器有重要的影响。
基于多线程或多进程的服务器无法适用于 WebSockets,因为它旨在打开连接,尽可能快地处理请求,然后关闭连接。任何实际的 WebSockets 服务器端实现都需要一个异步服务器。
案例
1)前端代码:
2)Nodejs socket后台:
到此这篇前端跨域解决方案怎么做(前端跨域解决方案怎么做的)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdkf/33769.html