同源策略:协议、域名、端口号必须完全相同。违背同源策略就是跨域。
注意:端口号为 9000
- 创建 index.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> <h1>HELLO AJAX</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>
- 创建 server.js 文件
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("服务已经启动..."); })
解决方案一、JSONP
JSONP(JSON with Padding),是一个非官方的跨域解决方案,只支持 get 请求。
- 创建 1-原理.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> <style> #result{ width:300px; height: 100px; border:solid 1px #78a; } </style> </head> <body> <div id="result"></div> <script> // 处理数据 function handle(data){ // 获取 result 元素 const result = document.getElementById('result') result.innerHTML = data.name } </script> <script 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.创建路由规则 //requset是对请求报文的封装 //response是对相应报文的封装 // jsonp服务 app.all('/jsonp-server',(request, response)=>{ // response.send('console.log("hello jsonp")') const data = { name: 'AJAX jsonp' } // 将数据转化为字符串 let str = JSON.stringify(data) // 返回结果 形式是函数调用 response.end(`handle(${str})`) }) //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
JSONP 实例(原生JSONP)
功能:在 input 框输入信息,发送请求(没有连接数据库,所有请求都按失败处理),当 input 框失去焦点时,边框变红色,提示用户已存在
- 创建 2-JSON实践.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>JSON案例</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>
- 创建 server.js 文件
//1.引入express const express = require('express'); //2.创建应用对象 const app = express(); //3.创建路由规则 // jsonp服务 app.all('/check-username',(request, response)=>{ // response.send('console.log("hello jsonp")') const data = { exist:1, msg:'用户名已经存在' } // 将数据转化为字符串 let str = JSON.stringify(data) // 返回结果 形式是函数调用 response.end(`handle(${str})`) }) //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
解决方案二、jQuery-jsonp
点击按钮,向 8000 端口发送请求,返回的结果在 div 中呈现
- 创建 3-jQuery-jsonp.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>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.6.0/jquery.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-josnp-server?callback=?',function(data){ $('#result').html(` 名称:${data.name},<br/> 校区:${data.city} `) }) }) </script> </body> </html>
- 创建 server.js 文件
//1.引入express const express = require('express'); //2.创建应用对象 const app = express(); //3.创建路由规则 // jQuery-jsonp服务 app.all('/jquery-josnp-server',(request, response)=>{ // response.send('console.log("hello jsonp")') const data = { name:'青岛', city: ['市南区','黄岛区'] } // 将数据转化为字符串 let str = JSON.stringify(data) // 接收 callback 参数 let cb = request.query.callback // 返回结果 形式是函数调用 response.end(`${cb}(${str})`) }) //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
解决方案三、CORS
CORS 是什么?
(1). CORS(Cross-Origin Resource Sharing),跨域资源共享。
(2).特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持 get 和 post 请求。
(3).跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。
CORS 怎么工作的?
主要是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
点击按钮,发送请求,响应内容
- 创建 cors.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>CORS</title> <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() // 4.绑定事件 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 服务 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.setHeader("Access-Control-Allow-Origin","http://127.0.0.1:5000") response.send('hello CORS') }) //4.监听端口启动服务 app.listen(8000, ()=>{ console.log("服务已经启动,8000 端口监听中..."); })
不积跬步无以至千里 不积小流无以成江海