前端跨域的几种方式
一、 什么是跨域
跨域(Cross-Origin)
是指在浏览器你执行脚本时,通过XMLHttpRequest、Fetch
等方式请求不同源(协议、域名、端口)的资源。同源策略是浏览器的一种安全机制,它限制了网页中的脚本只能与同源(相同协议、域名、端口)的资源进行交互,防止恶意网站获取用户的敏感信息或进行攻击。
在同源策略下。浏览器允许脚本访问同源的资源,但不允许访问不同域的资源。跨域请求会触发浏览器的安全机制,导致请求被拒绝。例如,如果网页在域名A下加载了一个脚本,而在这个脚本尝试访问域名B下的资源,浏览器阻止这个跨域请求。
对于前端开发来说,跨域请求是一个常见的问题,因为现代应用通常需要不同的服务器或域名上获取数据。为了实现跨域访问,开发者可以采用常用的一些常见的方式,如 JSONP、CORS、代理服务器或 WebSocket
等。这些允许前端页面与其他源的服务器进行安全的通信。
二、 前端跨域的几种方式
1、JSONP
JSONP(JSON with Padding)
是一种利用<script>
标签跨域获取数据的方法,可以绕过浏览器的同源策略限制。
JSONP
的原理如下:
- 通过请求参数作为回调函数的参数传递给服务器,服务器在响应中返回这个回调函数的调用,前端页面通过动态插入
<script>
标签来加载数据。 - 由于
<script>
标签不受同源策略的限制,因此可以跨域加载并执行返回的脚本。
以下是JSONP
的使用示例:
js
<script>
function callback(data) {
// 处理数据
}
</script>
<script src="http://example.com/api?callback=callback"></script>
上面的示例中,我们定义了一个名为callback
的函数,在之后的脚本中使用这个函数来处理返回的数据。通过将callback
函数的名称作为请求参数传递给服务器(例如: example.com/api?callbac... ),服务器在返回的响应中将调用该函数并传递数据。前端页面通过动态插入<script>
标签来加载这个跨域的脚本,并在脚本执行时用callback
函数来处理数据。
JSONP
的应用场景是在需要获取跨域数据时,由于同源策略的限制我们无法直接使用XMLHttpRequest 或 Fetch
方法时。比如说:我们需要从另一个域名的API
获取数据,而该API
支持JSONP
,我们可以使用JSONP
来实现跨域获取数据并在前端页面中进行处理。
JSONP
需要服务器直接返回可执行的脚本代码。此外,JSONP
只支持GET
请求,不支持POST
请求等其他类型的脚本。
2、CORS
CORS(跨域资源共享)
是一种通过在服务器配置响应头来实现跨域请求的机制。它允许在浏览器中进行安全的跨域通信,突破同源策略的限制。
CORS
的原理如下:
- 前端页面发送跨域请求给服务器。
- 服务器在响应头中添加
Access-Control-Allow-Origin
字段,指定允许跨域的源。例如,可以将其设置为Access-Control-Allow-Origin: http://example.com
。 - 浏览器收到带有这个响应头的请求后,会判断该请求是否在允许的跨域列表中,如果是则将响应返回给前端页面,否则会被浏览器拦截。
- 前端页面收到响应后,跨域像处理同源请求一样处理响应数据。
以下是CORS
的使用示例:
js
//服务器端响应头配置
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
//前端页面请求
fetch('http://example.com/api',{
method: 'GET',
mode: 'cors'
})
.then(response => response.json())
.then(data => {
//处理数据
});
在上面的示例中,服务器在响应头中添加了Access-Control-Allow-Origin
字段,指定允许跨域请求源为http://example.com
。前端页面在发送具有mode: 'cors'
的跨域请求时,浏览器会允许请求通过,并将响应返回给前端页面,使得前端跨域像处理同源请求一样处理跨域请求的响应数据。
CORS
的运用非常广泛,特别是在现代的Web
应用中。通过使用CORS
,前端跨域与其他域的服务器进行安全的跨域通信,实现数据的获取与交互。开发者跨域在服务器端配置CORS
响应头,来实现不同应用之间的跨域请求,提供更好的用户体验以及功能拓展。
3、前端代理服务器
前端代理服务器作为中间层。通过其中转,跨域绕过浏览器的同源限制,实现跨域请求。这种方法的优点是简单、灵活、适用于各种场景。
前端代理服务器的原理如下:
- 前端代理服务器位于浏览器和后端服务器之间,充当转发请求和响应的角色。
- 当浏览器发起跨域请求时,请求会先发送到前端代理服务器。
- 前端代理服务器收到请求后,根据根据配置的规则判断是否属于跨域请求。
- 如果属于跨域请求,前端代理服务器将发送新的请求到后端服务器,获取数据。
- 前端代理服务器收到后端服务器的响应后,将响应内容返回给浏览器。
以下是如何使用Node.js创建一个前端代理服务器:
js
const http = require('http');
const request = require('request');
const proxy = http.createServer((req,res) => {
//处理跨域请求
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods','GET,POST,PUT,DELETE');
//转发请求到后端服务器
const url = 'http://example.com' + req.url;
req.pipe(request(url)).pipe(res);
});
const port = 8080;
proxy.listen(port, () => {
console.log('Proxy server is running on port ${port}');
});
使用前端代理服务器的好处是可以方便地在开发环境中进行前后端分离,同时避免一些跨域请求带来地麻烦。但在生产环境中,建议采用更成熟地反向代理服务器,如Nginx
来处理跨域请求。
4、WebSocket
前端WebSocket
实现跨域的原理是基于浏览器的同源策略的限制,通过WebSocket协议进行通信。由于WebSocket
是基于TCP
协议的全双工通信协议,WebSocket
对象不受同源策略的约束,因此跨域实现跨域通信。
WebSocket
通信的实现原理:
- 在服务器端配置允许跨域请求:服务器端需要设置响应头,允许特定的域名访问该服务器资源。可以通过
Access-Control-Allow-Origin
进行跨域资源共享。 - 在前端使用
WebSocket
对象与服务器建立连接:在前端代码中,可以使用WebSocket
对象建立与目标服务器的连接。使用WebSocket
构造函数提供服务器的URL,例如:let socket = new WebSocket('ws://example.com/socket')
. - 进行
WebSocket
通信:一旦与服务器建立了WebSocket
连接,前端就可以通过WebSocket
对象发送和接收数据。可以使用WebSocket
对象的send()
方法发送数据,使用onmessage
时间监听接收到的信息,使用onopen
事件监听连接建立成功,使用onclose
事件建立连接关闭。
WebSocket
是HTML5
的新技术,不是所有的浏览器都支持。在使用WebSocket
实现跨域通信时,需要检查浏览器的兼容性并提供备选方案,确保在不支持WebSocket
的情况下仍能正常工作。