利用koa打造jsonp API


概述

最近學習利用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參數,值是我們要調用的函數名字,然后服務器返回一個字符串,這個字符串不僅僅是需要返回的數據,而且這個數據要用這個函數名字包裹。

所以我們需要做如下事情:

  1. 解析請求所帶的參數,並且讀取callback參數的值。解決方法是,我們用ctx.request.query獲得請求所帶的所有參數,然后讀取出callback參數:ctx.request.query.callback。
  2. 把數據轉化為字符串,並用這個函數名包裹。這個很簡單,字符串連接即可。

代碼如下:

'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跨域請求測試吧。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM