CORS配置
egg框架提供了 egg-cors 插件来实现CORS跨域请求,先配置插件,配置完毕后就可以使用了。前端使用的axios框架会将请求的数据处理这样请求的字符串数据会处理为对象,后端的egg框架在发送数据前也会将数据从对象处理为字符串才发送。
插件配置步骤:
//1.下载
npm i egg-cors
//2.开启插件,就是把插件引入到项目中
// config/plugin.js文件
cors:{
enable: true,
package: 'egg-cors',
}
//3.配置插件的功能,配置插件的功能必须写在声明的config对象下方,是const声明的在声明前操作会报错
// config/config.default.js文件
config.cors = {
//允许跨域的网址,*表示所有网址都可以跨域请求文件资源,也可以指定域名
origin: '*',
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
}
//默认origin只支持一个域名或者*表示全部,如果想支持具体的多个指定域名可以如下设置:
config.cors = {
// origin: ['http://localhost'],
origin:function(ctx) { //设置允许来自指定域名请求
console.log(ctx);
const whiteList = ['http://www.baidu.com','http://www.hqyj.com'];
let url = ctx.request.header.origin;
if(whiteList.includes(url)){
return url;
}
return 'http://localhost' //默认允许本地请求可跨域
},
allowMethods: 'GET,HEAD,PUT,POST,DELETE,PATCH'
};
使用插件进行跨域请求
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller } = app;
router.get('/', controller.home.index);
router.get("/aotu",controller.home.aotu);
//*星号路由,表示客户端随便输入什么pathname的网址都会执行controller文件夹下得home.js文件中得all函数
router.get("/*",controller.home.all);
};
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
const { ctx } = this;
ctx.body = 'hi, egg';
}
async aotu() {
this.ctx.body = 'anything is possible,你try try';
}
async all() {
this.ctx.body = 'hi,卤蛋';
}
}
module.exports = HomeController;
<body>
<button onclick="fn()">跨域请求数据</button>
<!-- 引入axios框架,做AJAX请求 -->
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.js" type="application/javascript"></script>
<script>
function fn(){
axios("http://192.168.0.109:7001/aotu")
.then((resquest)=>{
console.log(resquest);
});
};
</script>
</body>
JSONP配置
实现jsonp接口步骤
方式1:在配置文件中统一配置
//如果前端的URL中query参数中有cb=函数名参数(jsonp接口参数),将会返回JSONP格式的数据,否则返回JSON格式的数据。
//1.配置:
// config/config.default.js文件
config.jsonp = {
callback: 'cb', // 识别 query 中的 `cb` 参数
limit: 100, // 函数名最长为 100 个字符
};
//2.写接口
app/router.js
module.exports = app => {
const jsonp = app.jsonp();
app.router.get('/api/posts', jsonp, app.controller.posts.list);
};
方式2:在路由文件中配置,直接在jsonp方法中直接配置,
/// app/router.js文件
module.exports = app => {
const jsonp = app.jsonp({
callback: 'cb',
limit: 100,
});
app.router.get('/api/posts', jsonp, app.controller.posts.list);
};
使用方法
'use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
//形参解构赋值,形参app是一个对象,有router, controller这些成员
const { router, controller} = app;
router.get('/', controller.home.index);
router.get("/aotu",controller.home.aotu);
router.get("/data",app.jsonp({
callback:"cb"
}),controller.home.data);
//*星号路由,表示客户端随便输入什么pathname的网址都会执行controller文件夹下得home.js文件中得all函数
router.get("/*",controller.home.all);
};
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
const { ctx } = this;
ctx.body = 'hi, egg';
}
async aotu() {
this.ctx.body = 'anything is possible,你try try';
}
async all() {
this.ctx.body = 'hi,卤蛋';
}
async data() {
this.ctx.body = {info:"我是jsonp接口",code:666};
}
}
module.exports = HomeController;
<body>
<button onclick="fn()">跨域请求数据</button>
<button id="btn" onclick="fg()">跨域请求jsonp数据</button>
<!-- 引入axios框架,做AJAX请求 -->
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.js" type="application/javascript"></script>
<script>
function fn(){
axios("http://192.168.0.109:7001/aotu")
.then((resquest)=>{
console.log(resquest);
});
};
function fg(){
let fm="fm"+new Date().getTime();
window[fm]=function(jsdata){
console.log(jsdata);
};
let script=document.createElement("script");
script.src=`http://192.168.0.109:7001/data?cb=${fm}`
document.body.appendChild(script);
}
</script>
</body>
Proxy代理配置
egg中的网络请求技术:this.ctx.curl(url, option),请求数据后返回的是Promise对象,取值时需要用await。
option常用配置:
method:'GET/POST'
data:{name:"xxx"}//数据会自动字符串化
//home.js文件,写在controller文件夹下的js文件
async sina(){
let data1=await this.ctx.curl("http://www.baidu.com",{method:"GET",data:{pwd:123}})
this.ctx.body=data1
}
使用方法
async sina() {
let url="https://weibo.com";
let resquest=await this.ctx.curl(url);
this.ctx.body = resquest;
}
router.get("/sina",controller.home.sina);
<button class="proxy" onclick="fh()">go to sina</button>
<!-- 引入axios框架,做AJAX请求 -->
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/axios/0.26.0/axios.js" type="application/javascript"></script>
<script>
function fh(){
axios("/sina")
.then((resquest)=>{
console.log(resquest);
});
};
</script>