跨域
同源策略
同源策略(same-Origin-Policy)最早由Netscape公司提出,是浏览器的一种安全策略。
同源:协议、域名、端口号、必须完全相同。
违背同源策略就是跨域。
ajax默认遵从同源策略
同源策略:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>首页</title>
</head>
<body>
<h1>svt</h1>
<button>点击获取用户信息</button>
<script>
const btn=document.querySelector('button')
btn.onclick=function(){
const x=new XMLHttpRequest()
//因为这满足同源策略,所以url可以简写
x.open("GET",'/data');
x.send()
x.onreadystatechange=function(){
if(x.readyState===4){
if(x.status>=200&&x.status<300){
console.log(x.response);
}
}
}
}
</script>
</body>
</html>
const express=require('express')
const app=express()
app.get('/home',(req,res)=>{
res.sendFile(__dirname+'/index.html')
})
app.get('/data',(req,res)=>{
res.send("用户数据")
})
app.listen(9000,()=>{
console.log("服务已启动");
})
如何解决跨域
JSONP
- JSONP是什么
JSONP(JSON with Padding),是一个非官方的跨域解决方案,只支持get请求。 - JSONP是怎么工作的
在网页有一些标签天生具有跨域能力,比如:img link iframe script。
JSONP就是利用script标签的跨域能力来发送请求的。 - JSONP的使用
- 动态的创建一个script标签
var script=document.createElement(“script”); - 设置script的src,设置回调函数
script.src=“http://localhost:3000/testAJAX?callback=abc”;
- 动态的创建一个script标签
- 原理演示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>原理演示</title>
<style>
#result{
width: 300px;
height: 100px;
border: solid 1px #78a;
}
</style>
</head>
<body>
<div id="result"></div>
<script>
function handle(data){
const result=document.getElementById('result');
result.innerHTML=data.name;
}
</script>
<script src="http://127.0.0.1:8000/jsonp-server"></script>
<!-- <script src="http://127.0.0.1:5500/code/7-%E8%B7%A8%E5%9F%9F/2-JSONP/1-%E5%8E%9F%E7%90%86%E6%BC%94%E7%A4%BA.html"></script> -->
</body>
</html>
//jsonp服务
app.all('/jsonp-server',(req,res)=>{
const data={
name:'hoshihhh'
};
//将数据转化为字符串
let str=JSON.stringify(data);
//返回结果
res.end(`handle(${str})`);
})
- jsonp实践
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>案例</title>
</head>
<body>
用户名:<input type="text" id="username">
<p></p>
<script>
//获取input元素
const input=document.querySelector('input')
const p=document.querySelector('p')
//声明handle函数
function handle(data) {
input.style.border="solid 1px #f00";
//修改p标签的提示文本
p.innerHTML=data.msg;
}
//绑定事件
input.onblur=function(){
//获取用户的输入值
let username=this.value;
//向服务器发送请求 检测用户是否存在
//1.创建script标签
const script=document.createElement('script');
//2.设置标签的src属性
script.src='http://127.0.0.1:8000/check-username';
//3.将script插入到文档中
document.body.appendChild(script);
}
</script>
</body>
</html>
//用户名检测是否存在
app.all('/check-username',(req,res)=>{
const data={
exist:1,
msg:'用户名已存在'
};
//将数据转化为字符串
let str=JSON.stringify(data);
//返回结果
res.end(`handle(${str})`);
})
- jquery发送jsonp请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>jquery-jsonp</title>
<style>
#result{
width: 300px;
height: 100px;
border: solid 1px #089;
}
</style>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
</head>
<body>
<button>点击发送jsonp请求</button>
<div id="result"></div>
<script>
$('button').eq(0).click(function(){
$.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?',function (data) {
$('#result').html(`
名称:${data.name}<br>
区域:${data.city}
`)
})
})
</script>
</body>
</html>
app.all('/jquery-jsonp-server',(req,res)=>{
const data={
name:'hoshi',
city:['北京','上海','深圳']
};
//将数据转化为字符串
let str=JSON.stringify(data);
//接收callback参数
let cb=req.query.callback;
//返回结果
res.end(`${cb}(${str})`);
})
CORS
- CORS是什么?
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中处理,支持get和post请求。跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源 - CORS怎么工作的?
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该相应以后就会对响应放行。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CORS</title>
<style>
#result{
width: 300px;
height: 100px;
border: solid 1px #90b;
}
</style>
</head>
<body>
<button>发送请求</button>
<div id="result"></div>
<script>
const btn=document.querySelector('button')
btn.onclick=function(){
const x=new XMLHttpRequest();
x.open('GET','http://127.0.0.1:8000/cors-server');
x.send();
x.onreadystatechange=function(){
if(x.readyState===4){
if(x.status>=200&&x.status<300){
console.log(x.response);
}
}
}
}
</script>
</body>
</html>
app.all('/cors-server',(req,res)=>{
//设置响应头 设置允许跨域
res.setHeader('Access-Control-Allow-Origin','*');
//响应头
res.setHeader('Access-Control-Allow-Headers','*');
//响应方法
res.setHeader('Access-Control-Allow-Methods','*');
res.send('hello cors')
})
app.all('/cors-server',(req,res)=>{
//设置响应头 设置允许跨域
res.setHeader('Access-Control-Allow-Origin','*');
//响应头
res.setHeader('Access-Control-Allow-Headers','*');
//响应方法
res.setHeader('Access-Control-Allow-Methods','*');
res.send('hello cors')
})