概述
最近學習利用koa搭建API接口,小有所得,現在記錄下來,供以后開發時參考,相信對其他人也有用。
就目前我所知道的而言,API有2種,一種是jsonp這種API,前端通過ajax來進行跨域請求獲得數據;另一種是restful API,前端通過fetch或者axios進行cors請求來獲得數據。
本篇博文記錄我用koa打造的jsonp API。
參考資料:《Koa2進階學習筆記》,KOA docs
建一個服務器
首先用koa來建一個服務器,在這個過程中,我們用到了koa-logger中間件,它會在服務端顯示各種請求操作記錄,便於我們開發和調試。
//app.js
'use strict'
const Koa = require('koa');
const logger = require('koa-logger');
const app = new Koa();
app.use(logger());
app.listen(3000, () => {
console.log('koa starts at port 3000!');
})
注意:如果不能運行的話,就換一個端口!
babel
根據官網文檔,如果node版本大於7.6,就可以無痛使用async方法,否則要加入babel-register庫和transform-async-to-generator庫,並且在app.js里面加入如下代碼:
require('babel-register');
而且要在.babel
文件中,至少有如下代碼:
{
"plugins": ["transform-async-to-generator"]
}
路由
我們需要給jsonp的API新建一個路由,這樣就不影響其它路由了。(我們可能會在其它路由搭建restful api,也可能在其它路由搭建靜態頁面等等。)
'use strict'
const Koa = require('koa');
const logger = require('koa-logger');
const Router = require('koa-router');
const app = new Koa();
app.use(logger());
// 子路由1:主頁
let routerHome = new Router();
routerHome.get('/', async (ctx) => {
ctx.body = '歡迎歡迎!';
})
// 子路由2:jsonp api
let routerJsonp = new Router();
routerJsonp.get('/data1', async (ctx) => {
ctx.body = '數據';
})
// 裝載所有路由
let router = new Router();
router.use('/', routerHome.routes(), routerHome.allowedMethods());
router.use('/jsonp', routerJsonp.routes(), routerJsonp.allowedMethods());
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log('koa starts at port 3000!');
})
現在,先用node運行app.js文件,然后用瀏覽器訪問http://localhost:3000/
會看到歡迎歡迎四個字,訪問http://localhost:3000/jsonp/data1
會看到數據兩個字。
jsonp
jsonp的機制是,我們傳給服務器一個callback參數,值是我們要調用的函數名字,然后服務器返回一個字符串,這個字符串不僅僅是需要返回的數據,而且這個數據要用這個函數名字包裹。
所以我們需要做如下事情:
- 解析請求所帶的參數,並且讀取callback參數的值。解決方法是,我們用ctx.request.query獲得請求所帶的所有參數,然后讀取出callback參數:ctx.request.query.callback。
- 把數據轉化為字符串,並用這個函數名包裹。這個很簡單,字符串連接即可。
代碼如下:
'use strict'
const Koa = require('koa');
const logger = require('koa-logger');
const Router = require('koa-router');
const app = new Koa();
app.use(logger());
// 子路由1:主頁
let routerHome = new Router();
routerHome.get('/', async (ctx) => {
ctx.body = '歡迎歡迎!';
})
// 子路由2:jsonp api
let routerJsonp = new Router();
routerJsonp.get('/data1', async (ctx) => {
let cb = ctx.request.query.callback;
ctx.type = 'text';
ctx.body = cb + '(' + '"數據"' + ')';
})
// 裝載所有路由
let router = new Router();
router.use('/', routerHome.routes(), routerHome.allowedMethods());
router.use('/jsonp', routerJsonp.routes(), routerJsonp.allowedMethods());
app.use(router.routes()).use(router.allowedMethods());
app.listen(3000, () => {
console.log('koa starts at port 3000!');
})
最后用node運行app.js文件就大功告成了!!!我們首先在控制台引入jquery庫,然后調用jquery的ajax方法,進行jsonp請求,就能獲得“數據”了。
首先我們在瀏覽器的控制台引入jquery庫:
var myScript = document.createElement('script');
myScript.src = 'https://cdn.bootcss.com/jquery/3.3.1/jquery.js';
document.getElementsByTagName('head')[0].appendChild(myScript);
然后用ajax方法進行jsonp跨域請求數據,就可以在控制台看到“數據”二個字了。
$.ajax({
url : 'http://localhost:3000/jsonp/data1',
dataType : 'jsonp',
type : 'get',
success : function(res){
console.log(res);
},
error: function() {
alert("網絡出現錯誤,請刷新!");
}
});
注意:由於原頁面是http頁面,所以不能在https頁面進行jsonp跨域請求。找一個http頁面進行jsonp跨域請求測試吧。