跨域
跨域问题是前端开发常见的一个问题,就是当一个网页或脚本试图请求另一个来源(域名、协议或端口)的资源时会产生的问题。
原因是:浏览的同源策略。
同源策略规定了浏览器可进行的操作,如果不同源的网页或脚本没有授权,则无法读取或写入资源。
一般来说,当以下三个条件同时满足的时候,才会发生跨域问题:
- 1、浏览器限制,而不是服务端限制。
- 2、请求地址的域名或端口和当前访问的域名或端口不一样。
- 3、发送的是 XHR (XMLHttpRequest)请求。
JSONP
JSONP(JSON with Padding)的思想是通过页面上动态创建 <script>
标签,从另一个域加载包含 JSON 数据的外部脚本文件,然后将数据包裹在一个函数调用中返回给客户端。
具体工作流程是:
- 1、客户端定义一个回调函数,将其名称作为参数传递给服务端。
- 2、服务端收到请求后,将数据包装在回调函数中。
- 3、服务端将回调函数返回给客户端。
- 4、客户端执行回调函数,从而获取服务端的回调函数。
// 定义回调函数
function handleResponse(response) {
console.log("Received data: ", response);
}
// 创建一个新的<script>元素
var script = document.createElement('script');
// 设置src属性,其中myCallback是服务端期望的回调函数名
script.src = 'https://example.com/data?callback=handleResponse';
// 将<script>元素插入到页面中,这将导致浏览器发送请求
document.head.appendChild(script);
CORS
**CORS(Cross-Origin Resource Sharing,跨资源共享)**允许服务器标识除自己以外的其他源,使得浏览器允许这些资源访问加载自己的资源。
它的一个核心机制是预检。预检请求是浏览器正式发送跨域请求之前,向服务器发起的一个预先询问的请求,就是询问服务器是否允许它进行跨域请求。
预检请求报文中 :
Access-Control-Request-Method
告诉服务器所请求的的 HTTP 方法。Access-Control-Request-Headers
告诉服务器实际请求携带的自定义首部字段。Access-COntrol-Allow-Methods
告诉服务器所有允许的请求方法。
// JavaScript代码,使用Fetch API发起跨域请求
fetch('https://example.com/data', {
method: 'GET', // 或者 'POST'
headers: {
'Content-Type': 'application/json',
},
})
.then(response => response.json())
.then(data => console.log(data))
.catch((error) => {
console.error('Error:', error);
});
// Java代码,使用Spring框架设置响应头
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@CrossOrigin(origins = "http://localhost:3000")
@GetMapping("/data")
public String getData() {
// 返回一些数据
return "Hello, CORS!";
}
}