
同源策略是浏览器的一种安全策略。
同源策略:即 网页的url 和 该网页请求的url 的协议、域名、端口必须保持一致。
协议、域名、端口必须保持一致就是说网页的加载服务器和页面请求的请求服务器是同一个服务器的同一个服务。
ajax默认支持同源策略。
图示理解:
在url上表示为:
网页的url是 http://a.com:8080,那么网页请求的url也必须是 http://a.com:8080
eg:同源策略
html:
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>首页title>
head>
<body>
<h2>首页h2>
<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>
server.js
const { response, request } = require('express');
const express = require('express');
const app = express();
app.get('/home', (request, response) => {
// 响应一个页面
response.sendFile(__dirname + '/index.html');
});
app.get('/data', (request,response) => {
response.send('用户数据')
})
app.listen(9000, () => {
console.log('服务已启动……');
})
输出:
违背同源策略就是跨域。
即如果网页请求的url 和 网页的url 的协议、域名、端口任意一项不同就是跨域。
JSONP(JSON with Padding),是一个非官方的跨域解决方案,纯粹凭借程序员的聪明才智开发出来,只支持get请求。
在网页有一些标签天生具有跨域能力,比如: img link iframe script.
JSONP就是利用script标签的跨域能力来发送请求的。
eg:
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>Documenttitle>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.27.2/axios.js">script>
head>
<body>
<div class="container">
<h2 class="page-header">jQuery发送AJAX请求h2>
<button class="btn btn-primary">GETbutton>
<button class="btn btn-danger">POSTbutton>
<button class="btn btn-info">通用型方法ajaxbutton>
div>
<script>
const btns =document.querySelectorAll('button')
axios.defaults.baseURL = 'http://127.0.0.1:8000'
btns[0].onclick =function(){
// get请求
axios.get('/axios-server',{
// 参数:
params:{
id:100,
vip:7
},
// 请求头
headers:{
name:'yang',
// age:20
}
}).then(value =>{
// 响应体结果
console.log(value)
})
}
btns[1].onclick =function(){
// get请求
axios.post('/axios-server',
{// 请求体
username:'admin',
password:'admin'
},{
// 参数:
params:{
id:200,
vip:9
},
// 请求头
headers:{
heigth:200,
width:200
}
})
}
btns[2].onclick = function (){
axios({
// 请求方法:
method:'POST',
// url
url:'/axios-server',
// 参数
params:{
vip:10,
level:30
},
// 请求头
headers:{
heigth:200,
width:200
},
// 请求体
data:{
username:'admin',
password:'admin'
}
}).then(response=>{
// console.log(response)
//响应状态码
console.log(response.status);
//响应状态字符串
console.log(response.statusText);
//响应头信息
console.log(response.headers);
//响应体
console.log(response.data);
})
}
script>
body>
html>
引入的是远端内容,而网页请求url是:http://127.0.0.1:8000,这是跨域请求,但是能正常访问。
利用script标签的跨域能力:
原理.html
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>
#result{
width: 300px;
height: 100px;
border:solid 1px darkcyan;
}
style>
head>
<body>
<div id='result'>div>
<script>
function handle(data) {
// 获取result
const result = document.getElementById('result');
result.innerHTML = data.name;
}
script>
<script type='text/javascript' src='http://localhost:8080/jsonp/app.js'>script>
body>
html>
app.js
const data = {
name:'@yang'
}
handle(data);
原理.html会向app.js发送请求,app.js的响应结果是app.js的内容。
ajax默认情况下是不可以进行跨域请求的,我们可以使用jsonp请求来实现跨域请求:
使用script标签进行服务器请求script的返回结果需要是js能够解析的语句,所以jsonp请求的响应结果一般是一个函数调用,而函数调用的实参一般是我们想要返回给前端的数据。(该函数应该是前端js定义好的函数)
eg:
html:
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>
#result{
width: 300px;
height: 100px;
border:solid 1px darkcyan;
}
style>
head>
<body>
<div id='result'>div>
<script>
function handle(data) {
// 获取result
const result = document.getElementById('result');
result.innerHTML = data.name;
}
script>
<script type='text/javascript' src='http://127.0.0.1:8000/jsonp-server'>script>
body>
html>
server.js:
// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();
// 3.创建路由规则
// jsonp服务
app.all('/jsonp-server', (request, response) => {
const data = {
name:'hello yang'
}
let str = JSON.stringify(data)
response.end(`handle(${str})`)
})
// 4.监听端口启动服务
app.listen(8000, () => {
console.log('服务已经启动,8000端口监听中……')
})
输出:
使用jsonp的步骤
// 1. 创建script标签
const script = document.createElement('script')
// 2. 设置script的src
script.src = 'http://127.0.0.1:8000/check-username'
// 3.将script插入到文档中,插入到body最后
document.body.appendChild(script);
eg:需求:输入框失去焦点的时候向服务器发送请求,返回应户名已存在。
html:
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>Documenttitle>
head>
<body>
用户名: <input type="text" id='username'>
<p>p>
<script>
const input = document.querySelector('input');
const p = document.querySelector('p')
function handle(data){
input.style.border = 'solid 1px #f00'
p.innerHTML= data.msg
}
input.onblur = function (){
let username = this.value
// 向服务端发送请求
// 1. 创建script标签
const script = document.createElement('script')
// 2. 设置script的src
script.src = 'http://127.0.0.1:8000/check-username'
// 3.将script插入到文档中,插入到body最后
document.body.appendChild(script);
}
script>
body>
html>
server.js
// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();
// 3.创建路由规则
// 用户名检测
app.all('/check-username', (request, response) => {
const data = {
exist: 1,
msg:'用户名已存在'
}
let str = JSON.stringify(data)
response.end(`handle(${str})`)
})
// 4.监听端口启动服务
app.listen(8000, () => {
console.log('服务已经启动,8000端口监听中……')
})
运行结果:
格式:$.getJSON('url?callback=?',function (data){})
callback=?是固定写法,而且callback在实际请求中是有参数的。
eg:
实例:
html
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>Documenttitle>
<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js">script>
<style>
#result{
width: 300px;
height: 100px;
border:solid 1px #089;
}
style>
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}
城市:${data.city}
`)
})
})
script>
body>
html>
js:
// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();
// 3.创建路由规则
// jquery发送jsonp
app.all('/jquery-jsonp-server', (request, response) => {
const data = {
name: 'yang',
city:'beijing'
}
// 将数据转换成字符串
let str = JSON.stringify(data)
// 接收callback参数
let cb = request.query.callback;
// 返回结果
response.end(`${cb}(${str})`)
})
// 4.监听端口启动服务
app.listen(8000, () => {
console.log('服务已经启动,8000端口监听中……')
})
CORS解决跨域请求
CORS是什么?
CORS (Cross-Origin Resource Sharing),跨域资源共享。
CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的 *** 作,完全在服务器中进行处理,支持get和 post请求。
跨域资源共享标准新增了一组HTTP首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
使用cors实现ajax的跨域请求如果不使用cors解决跨域请求ajax会报如下错误:
使用cors实现ajax的跨域请求只需要在服务器端添加如下语句
response.setHeader('Access-Control-Allow-Origin','*');
设置响应头 设置允许跨越,*代表可以跨域到所有网页。
响应头不止一种们可以在如下网页进行查看:
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
一般情况下我们设置下面3种:
// 设置响应头 设置允许跨越,*代表可以跨域到所有网页
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置允许自定义请求头信息
response.setHeader('Access-Control-Allow-Headers', '*');
// 设允许所有请求类型
response.setHeader('Access-Control-Allow-Method','*');
eg:
html
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>Documenttitle>
<style>
#result{
width: 200px;
height: 100px;
border: solid 1px #90b;
}
style>
head>
<body>
<button>发送请求button>
<div id='result'>div>
<script>
const btn = document.querySelector('button')
btn.onclick = function (){
// 1.创建对象
const x = new XMLHttpRequest();
// 2.初始化
x.open('GET','http://127.0.0.1:8000/cors-server')
// 3.发送
x.send()
// 处理结果
x.onreadystatechange = function (){
if(x.readyState === 4){
if(x.status>=200 && x.status<300){
console.log(x.response);
}
}
}
}
script>
body>
html>
server.js
// 1.引入express
const express = require('express');
// 2.创建应用对象
const app = express();
// 3.创建路由规则
// cors-server
// cors-server
app.all('/cors-server', (request, response) => {
// 设置响应头 设置允许跨越,*代表可以跨域到所有网页
response.setHeader('Access-Control-Allow-Origin', '*');
// 设置允许自定义请求头信息
response.setHeader('Access-Control-Allow-Headers', '*');
// 设允许所有请求类型
response.setHeader('Access-Control-Allow-Method','*');
response.send('Hello CORS')
})
// 4.监听端口启动服务
app.listen(8000, () => {
console.log('服务已经启动,8000端口监听中……')
})
补充:所有响应头种类见这里
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)