AJAX
同源策略
同源策略(Same-Origin Pollicy)是浏览器的一种安全策略
同源:协议、域名、端口号必须完全相同
ajax默认是遵从同源策略,违背同源策略就是跨域
页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h3>跨域</h3>
<button>点击获取用户数据</button>
<script>
const btn = document.querySelector('button');
btn.onclick = function() {
const xhr = new XMLHttpRequest();
// 这个index.html页面是通过访问服务器然后打开的,所以满足同源
// 如果满足同源策略,url可以简写
xhr.open('GET', '/data');
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.response); //用户数据
}
}
}
}
</script>
</body>
</html>
接口
// 跨域
const express = require('express');
const app = express();
app.get('/home', (req, res) => {
// 访问这个接口,打开index.html页面
res.sendFile(__dirname + '/index.html');
});
app.get('/data', (req, res) => {
res.send('用户数据');
});
app.listen(8004, () => {
// http://localhost:8004/home
console.log('8004 的服务器已启动');
})
如何解决跨域?
1.JSONP
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来的饿,只支持get请求
JSONP是利用script标签的跨域能力来发送请求的,只支持get请求
具有跨域能力的标签:img\link\iframe\script
JSONP的使用
原理
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jsonp原理演示</title>
<style>
#box {
width: 200px;
height: 200px;
border: 1px solid chocolate;
border-radius: 5px;
}
</style>
</head>
<body>
<div id="box"></div>
<!-- script标签具有跨域能力 -->
<!-- 先加载了handler函数 -->
<script>
function handler(res) {
const box = document.getElementById('box');
box.innerHTML = res.name;
}
</script>
<!-- <script src="./app.js"></script>
-->
<!-- 然后再请求后台获取数据 -->
<script src="http://localhost:8004/jsonp"></script>
</body>
</html>
app.js
const data = {
name: 'zs'
};
// console.log(data);
// function handler(res) {
// const box = document.getElementById('box');
// box.innerHTML = res.name;
// }
handler(data)
接口
app.get('/jsonp', (req, res) => {
// res.send('console.log("jsonp原理")');
const data = {
name: 'zs'
};
// 将数据转化为字符串
let str = JSON.stringify(data);
// 处理返回的数据
// 返回的结果是函数的调用,函数的参数就是要传递过去的数据
res.send(`handler(${str})`);
});
CORS
cors(Cross-Origin Resource Sharing,跨域资源共享),cors是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get和post请求,跨域资源共享标准新增了一组HTTP的首部字段,允许服务器声明哪些源站通过浏览器有权限访问那些资源
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#box {
width: 200px;
height: 200px;
border: 1px solid firebrick;
border-radius: 5px;
}
</style>
</head>
<body>
<button>发送请求</button>
<div id="box"></div>
<script>
const btn = document.querySelector('button');
btn.onclick = function() {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:8004/cors');
xhr.send();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
console.log(xhr.response);
}
}
}
}
</script>
</body>
</html>
接口
app.all('/cors', (req, res) => {
// 设置响应头,允许所有的网页跨域
res.setHeader('Access-Control-Allow-Origin', '*');
// 可自定义头信息
res.setHeader('Access-Control-Allow-Headers', '*');
// 哪个请求方式都可以
res.setHeader('Access-Control-Allow-Method', '*');
// 只允许http://127.0.0.1:5500这个访问跨域
// res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500');
res.send('cors');
})