自己練習(xí)用koa2去寫接口的時(shí)候,遇到了ajax請(qǐng)求GET接口,例如如下
$.ajax({
type: "GET",
url:'http://localhost:3000/user_new',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=utf-8',
'Authorization': 'JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoiNTJjYjA5MjFjMjM0NDgzODhjMDQ1Mzg2N2QzZDI0NzUiLCJjb21wYW55X2lkIjoiNzM2ZDc5YjQ1NTkzNDU2NWE4ODljYjJmOTBhOTNlNzIiLCJzdGFmZl9pZCI6IjhlODM2MjFmZjQ3YTRhZGY4NjU4NGNhNWYxNDRmYzc0IiwidGVuYW50X2lkIjoiMTliMDQyMGM3ODViNGNlN2IxODNmMTFjMjY0M2I4YmUifQ.D7Mrba-lB94iSWr2pHAtS4KUkC_g06lJVHutj0MIu1Q'
},
success: function (data, textStatus) {
console.log('123123')
},
error: function (a,b,c) {
console.log('2222222')
}
})
然后會(huì)發(fā)生一次OPTIONS的請(qǐng)求,但是一直接受不到,koa2的代碼如下
const fn_usrs = async (ctx, next) => {
let cb = ctx.request.query.callback;
if (cb) { //ajax jsonp的請(qǐng)求方式
ctx.response.body = cb + '(' + JSON.stringify(jsonData) + ')';
}else{ //
// ctx.set("Access-Control-Allow-Origin", "*") //ajax json的形式允許都跨域進(jìn)入
ctx.response.body = '{}'; //proxy 代理的方式
}
}
const fn_usrs_option = async(ctx, next) => {
// ctx.set("Access-Control-Allow-Origin", "*");
if (ctx.request.method == "OPTIONS") {
ctx.response.status = 200
}
ctx.response.status = 200
}
module.exports = {
'GET /user_new': fn_usrs_new,
'OPTIONS /user_new': fn_usrs_option,
};
可是瀏覽器卻一直顯示的是404 找不到,也沒有走'OPTIONS /user_new': fn_usrs_option,
也沒有走這個(gè)'GET /user_new': fn_usrs_new,
koa2代碼的index.js如下
const Koa = require('koa');
const app = new Koa();
const path = require('path');
const static = require('koa-static');
const bodyParser = require('koa-bodyparser');
const router = require('koa-router')();
const controller = require('./server/index.js');
// 部署靜態(tài)資源
const staticPath = './static';
app.use(static(
path.join( __dirname, staticPath)
))
// ejs 模版引擎
const views = require('koa-views')
app.use(views(path.join(__dirname, './view'), {
extension: 'ejs'
}))
// 集中處理錯(cuò)誤
const handler = async (ctx, next) => {
// log request URL:
// ctx.set("Access-Control-Allow-Origin", "*");
// ctx.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
console.log(`Process ${ctx.request.method} ${ctx.request.url}`);
try {
await next();
console.log('handler通過')
} catch (err) {
console.log('handler處理錯(cuò)誤')
ctx.response.status = err.statusCode || err.status || 500;
ctx.response.body = {
message: err.message
};
}
};
// 如果錯(cuò)誤被catch. 就不會(huì)出發(fā)onerror時(shí)間,需要調(diào)用 ctx.app.emit('error', err, ctx);
// app.on('error', function(err) {
// console.log('logging error ', err.message);
// });
app.use(handler)
app.use(bodyParser()); //合適的位置 解析post請(qǐng)求的
app.use(controller()) // 服務(wù)的位置 ----也是寫路由的位置
app.listen(3000, () => {
console.log('app started at port 3000...');
});
controller 文件的內(nèi)容如下
const fs = require('fs');
function addMapping(router, mapping) {
for (var url in mapping) {
if (url.startsWith('GET ')) {
var path = url.substring(4);
router.get(path, mapping[url]);
// console.log(`register URL mapping: GET ${path}`);
} else if (url.startsWith('OPTIONS ')) {
var path = url.substring(8);
router.get(path, mapping[url]);
} else if (url.startsWith('POST ')) {
var path = url.substring(5);
router.post(path, mapping[url]);
// console.log(`register URL mapping: POST ${path}`);
} else if (url.startsWith('PUT ')) {
var path = url.substring(4);
router.put(path, mapping[url]);
// console.log(`register URL mapping: PUT ${path}`);
} else if (url.startsWith('DELETE ')) {
var path = url.substring(7);
router.del(path, mapping[url]);
// console.log(`register URL mapping: DELETE ${path}`);
} else {
console.log(`invalid URL: ${url}`);
}
}
}
function addControllers(router, dir) {
const files = fs.readdirSync(__dirname + '/' + dir).filter((f) => {
return f !== 'index.js';
})
files.forEach((f) => {
// console.log(`process controller: ${f}...`);
let mapping = require(__dirname + '/' + f);
addMapping(router, mapping);
});
}
module.exports = function(dir) {
let controllers_dir = dir || '/',
router = require('koa-router')();
addControllers(router, controllers_dir);
return router.routes();
};
調(diào)用的時(shí)候直接打印了process和handler通過。不知道為什么?找了很多原因也沒有找到
module.exports = {
'GET /user_new': fn_usrs_new,
'OPTIONS /user_new': fn_usrs_option,
'GET /users': fn_usrs,
'POST /users': add_usrs,
'DELETE /users/:id': del_usrs,
};
這個(gè)是路由的地址,接口的地址,我本地的服務(wù),
解決的方法就是在集中處理錯(cuò)誤的地方統(tǒng)一設(shè)置
ctx.set("Access-Control-Allow-Origin", "*");
ctx.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
ctx.set("Access-Control-Max-Age", "3600");
ctx.set("Access-Control-Allow-Headers", "x-requested-with,Authorization,Content-Type,Accept");
ctx.set("Access-Control-Allow-Credentials", "true");
這些東西,可以挑著用,看項(xiàng)目的需要。其次還有就是OPTIONS確實(shí)是router內(nèi)容自己處理,我們不需要處理,只需要告訴OPTIONS請(qǐng)求返回200就行,上面的函數(shù)也就變成了下面這個(gè)樣子
// 集中處理錯(cuò)誤
const handler = async (ctx, next) => {
// log request URL:
ctx.set("Access-Control-Allow-Origin", "*");
ctx.set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
ctx.set("Access-Control-Max-Age", "3600");
ctx.set("Access-Control-Allow-Headers", "x-requested-with,Authorization,Content-Type,Accept");
ctx.set("Access-Control-Allow-Credentials", "true");
if (ctx.request.method == "OPTIONS") {
ctx.response.status = 200
}
console.log(`Process ${ctx.request.method} ${ctx.request.url}`);
try {
await next();
console.log('handler通過')
} catch (err) {
console.log('handler處理錯(cuò)誤')
ctx.response.status = err.statusCode || err.status || 500;
ctx.response.body = {
message: err.message
};
}
};
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
北大青鳥中博軟件學(xué)院創(chuàng)立于2003年,作為華東區(qū)著名互聯(lián)網(wǎng)學(xué)院和江蘇省首批服務(wù)外包人才培訓(xùn)基地,中博成功培育了近30000名軟件工程師走向高薪崗位,合作企業(yè)超4
中公教育集團(tuán)創(chuàng)建于1999年,經(jīng)過二十年潛心發(fā)展,已由一家北大畢業(yè)生自主創(chuàng)業(yè)的信息技術(shù)與教育服務(wù)機(jī)構(gòu),發(fā)展為教育服務(wù)業(yè)的綜合性企業(yè)集團(tuán),成為集合面授教學(xué)培訓(xùn)、網(wǎng)
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國成功上市,融資1
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。