跨域
跨域是指发送请求的客户端和服务器之间,它们的 协议、域名/IP地址、端口号 三者中任意一个不相同 (由于浏览器的同源策略,禁止js从一个域名向另一个域名请求数据)
解决方式
配置CORS跨域资源共享(xhr2)
CORS允许浏览器向跨域服务器发送ajax请求
服务端
//创建模块
cost express = require('express')
const cors = require('cors')
//创建服务
let app = express()
app.use(cors())
cors中间件其实做了下列事情:
app.all("*",function(req,res,next){
//设置允许跨域的域名,*代表允许任意域名访问
res.header("Access-Control-Allow-Origin","*")
//允许的header类型
res.header("Access-Control-Allow-Headers","Content-Type")
//允许的跨域请求方式
res.header("Access-Control-Allow-Methods","POST,GET")
next()
})
服务端代理转发(nodejs nginx webpack ...)
服务端没有跨域限制: 前端发送请求 <-> 自己的服务器 <-> 请求别人的服务器
-
node js
客户端:传入地址let target = 'https://m.you.163.com/xhr/index.json'; //跨域地址 ajax({ url: 'http://localhost:9999/user/proxy',// 访问同源地址 data: {url:target}//传入地址 })服务端:设置代理接口const http = require('http') app.get('/proxy',(req,res)=>{ let {url} = req.query let data = '' http.get(url,(response)=>{ //收到一个数据片段时,触发data事件 response.on('data',(chunk)=>{ console.log('------------------')//分割流 data += chunk }) //数据片段传输完成后,触发end事件 response.on('end',()=>{ res.send(data) }) }) }) -
nginx:设置接口 (客户端:访问同源地址)
服务端location = /proxy { proxy_pass 'https://m.you.163.com/xhr/index.json' //跨域地址 }
使用jsonp跨域:只能适用get请求
jsonp是指跨域获取json数据
- 由于浏览器的同源策略,禁止js跨域请求数据
- 但是,浏览器不限制link img script等标签的跨域获取资源的能力
- script标签,浏览器自动解析js
jsonp的实现:
- 1.动态创建script标签
- 2.将接口地址赋值给src属性,并在地址后面拼接参数
- 3.将script标签添加到页面中
- 客户端创建全局函数
- 服务端调用函数,返回数据
- 4.数据加载完成后,删除script标签
客户端:创建全局函数并添加script标签
// 1.动态创建script标签
let myScript = document.createElement('script');
// 2.将接口地址赋值给src属性,并在地址后面拼接参数
myScript.src = 'http://localhost:2000/user/jsonp?callback=test';
// 3.将script标签添加到页面中
document.body.appendChild(myScript);
// 4.数据加载完成后,删除script标签
myScript.onload = function (){
this.remove();
}
//创建全局函数
function test(json){
console.log( '成功',json );//返回json对象 -> 浏览器自动解析js
}
服务端:接收回调函数
app.get('/jsonp',(req,res)=>{
//接收全局函数
let {callback} = req.query
let data = {
username:'哈哈',
age:20
}
res.send(`${callback}(${JSON.stringify(data)})`)//data为json字符串
//res.send(test(data))
})