### CORS跨域资源共享及其解决方案详解
#### 一、CORS跨域资源共享背景
在现代Web应用开发中,前后端分离已成为一种主流趋势。在这种模式下,前端负责展示逻辑,而后端处理业务逻辑与数据交互。然而,由于浏览器出于安全考虑实施了同源策略,这导致了跨域问题的发生。
**同源策略**是指一个Web页面只能访问与其具有相同协议、相同域名和相同端口的其他Web页面。具体来说:
- **相同协议**:如HTTP或HTTPS。
- **相同域名**:如example.com。
- **相同端口**:如80或443。
当前后端不在同一源时,就会遇到跨域问题。为了解决这一问题,跨域资源共享(CORS)应运而生。CORS是一种机制,通过添加HTTP头来告诉浏览器允许跨源访问。
#### 二、CORS的工作原理
CORS根据请求的不同类型分为**简单请求**和**非简单请求**。
##### 1. 简单请求
当请求符合以下条件时,被视为简单请求:
- 使用了以下方法之一:`GET`、`HEAD` 或 `POST`。
- HTTP头部信息不超过以下字段集:`Accept`, `Accept-Language`, `Content-Language`, `Content-Type`(且`Content-Type`的值仅限于`text/plain`, `multipart/form-data`, `application/x-www-form-urlencoded`)。
简单请求不会触发预检请求(即`OPTIONS`请求),而是直接发送实际请求。
##### 2. 非简单请求
对于不符合简单请求标准的请求,浏览器会首先发送一个预检请求(`OPTIONS`)来确认服务器是否允许该跨域请求。预检请求成功后才会发送实际请求。
预检请求包含以下关键头部信息:
- `Access-Control-Request-Method`:表明实际请求所使用的方法。
- `Access-Control-Request-Headers`:列出实际请求中的自定义头部信息。
服务器响应预检请求时,需要包含如下头部信息:
- `Access-Control-Allow-Origin`:指定允许发起请求的源。
- `Access-Control-Allow-Methods`:表明服务器支持哪些方法。
- `Access-Control-Allow-Headers`:指定实际请求中可以使用的头部字段。
- 可选:`Access-Control-Max-Age`,用于缓存预检请求结果。
#### 三、CORS实现示例
假设有一个前端应用运行在`http://localhost:8080/`,而后端API位于`http://localhost:3000/`。
##### 前端示例代码
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CORS Example</title>
</head>
<body>
<script defer src="http://localhost:3000/test_jsonp?callback=callback"></script>
<script>
var callback = function (res) {
console.log(res);
};
</script>
</body>
</html>
```
##### 后端示例代码
```javascript
var express = require('express');
var router = express.Router();
var querystring = require('querystring');
router.get('/test_jsonp', function (req, res, next) {
let params = querystring.parse(req.url.split('?')[1]);
let obj = {
name: '张三',
sex: '男'
};
res.writeHead(200, {'Content-Type': 'text/javascript'});
res.write(params['callback'] + '(' + JSON.stringify(obj) + ')');
});
router.listen(3000, function () {
console.log('Server running on port 3000');
});
```
为了使CORS工作,我们需要在后端服务端添加如下代码以允许跨域访问:
```javascript
res.setHeader('Access-Control-Allow-Origin', '*');
```
#### 四、使用JSONP解决跨域问题
JSONP(JSON with Padding)是一种解决跨域问题的技术,其核心思想是利用HTML标签(如`<img>`、`<script>`等)可以加载任意来源的资源这一特性。在上述示例中,通过将数据嵌入到回调函数中并作为`<script>`标签的源文件来实现跨域访问。
JSONP的主要步骤包括:
1. 在前端页面中动态插入一个`<script>`标签,并将其`src`属性设置为目标URL。
2. URL中通常包含一个查询参数,用于指定回调函数的名称。
3. 服务器端接收到请求后,将数据封装在回调函数中返回。
4. 浏览器执行`<script>`标签内的JavaScript代码,从而实现跨域数据传输。
通过以上介绍可以看出,CORS提供了一种更加灵活、安全的方式来解决跨域问题,而JSONP则是在CORS不适用的情况下的另一种选择。开发者可以根据实际情况选择最合适的方法来解决跨域问题。
- 1
- 2
前往页