# JS插件基本操作

以下演示JS插件的基本操作,让大家使用JS插件开发webapi有一个初步的入门。

# 获取Http请求参数

我们修改上一节的示例代码app中添加一个basic函数如下:

let app = {
   //除了定义的函数外,/js 开头的所有请求都会进入该处
   _all(ctx,r,w) {
       let data = {msg:"操作成功",code:200};
       w.write(data);
   },
   basic(ctx,r,w) {
   	let data = {
   		url:r.url.path ,				//url路径
   		rawQuery:r.url.rawQuery,		//原始请求
   		mykey:r.header.get("mykey"),	//header的值
   		qry:r.url.query.get("qry"),		//url中带的参数
   		method:r.method,				//http请求方法post/get等
   		remoteAddr:r.remoteAddr,		//发起请求的ip
   		host:r.host,					//请求的主机
   		formvalue:r.formValue("qry")	//form表单中的qry字段
   	}
   	
   	//设置返回的header值
   	w.header.set("Content-type","application/json")
   	w.header.set("key1","123456")
   	w.write(data);
   }
}

浏览器中输入 http://127.0.0.1:5555/js/basic?qry=123 (opens new window)

提示: 此处url的basic会自动路由到定义的basic方法中。

得到如下值:

{"url":"/js/basic","rawQuery":"qry=123","mykey":"","qry":"123","method":"GET","remoteAddr":"127.0.0.1:29620","host":"127.0.0.1:5555","formvalue":"123"}

# Session操作

由于http是无状态的,webapi在两次http调用中需要知道上一次操作后的值,比如判断是否登录,此时可以通过session保存登录状态和用户名等信息。
我们修改上一节的示例代码app中添加一个session函数如下:

session(ctx,r,w) {
    //取请求的session,如果没有会自动创建session
    let session = ctx.sessionStart();
    let name = session.get('name');	//不存在这个key时返回''
    if (name === '') {
        w.write({msg:'session name没有值'})
        session.set('name','小明')	//设置session值,下一次可以取到
    } else {
        w.write({msg:'session:' + name });
        session.free()	//删除session
    }
}

浏览器中输入 http://127.0.0.1:5555/js/session (opens new window) 不停地刷新可以看到返回数据的变化

# 文件操作

返回服务端的文件到浏览器或者请求的客户端, 我们修改上一节的示例代码app中添加一个testServe函数如下:

testServe(ctx,r,w) {
    //返回服务端satserver相同目录下面的文件
    ctx.serveContent("myapp/login.html")
}

浏览器中输入 http://127.0.0.1:5555/js/testServe (opens new window) 可以返回login.html到浏览器,这里没有返回页面的css,js等资源,可以在_all函数中加入判断是否资源文件进行返回(可以自己验证)。

# Http请求

服务端有时需要请求其它webapi,如微信接口、医保接口等,这时需要调用Http请求完成。 我们在示例代码app对象中添加testHttpPost和testHttpGet函数如下:

	testHttpPost(ctx,r,w) {
		let http = satrda.Http;
		let resp = http.post("http://127.0.0.1:5555/restful/rpc",{ db:"mycon1",function:"sp_fun_test", in1:10.1,in2:"就是这么简单" })
		console.log(resp.header.get("content-type"))
		
		//返回的resp.body是二进制数据,得到是json数据可以写resp.jsonBody
		let info = resp.body;
		let data = satrda.decodeUtf8(info);
		data = JSON.parse(data);
		w.write(data);
	},
	testHttpGet(ctx,r,w) {
		let http = satrda.Http;
		let resp = http.get('http://www.baidu.com')
		console.log(resp.header.get("content-type"))
		//返回的resp.body是二进制数据,得到json数据可以写resp.jsonBody
		let info = resp.body;
		let data = satrda.decodeUtf8(info);
		w.header.set("Content-type","text/html;charset=utf-8")
		w.write(data);
	}

验证可以在浏览器中输入

# 数据库操作

通过JS插件可以实现数据库的增删查改等操作, 我们在示例代码app对象中添加testDB函数如下:

testDB(context,r,w) {
	try{
		let db = new satrda.DataBase();
		db.open("mycon1","cc1","");		//打开数据连接mycon1
		let rs = db.query("select count(0) from test1");
		let data = {
			count:0
		}
		
		//获取单行数据,再次调用可以获取下一行
		if ( !rs.fetch() ) {
			w.write(data);
			return;
		} 
		
		//取得当前行第一列数据,等同于rs.getLong(0),也可以通过列名使用rs.getLong('colname')
		data.count = rs.getLong();
		rs.close(); //关闭resultset
		if ( data.count > 0) {
			let rs = db.query("select id,name,price,des from test1");
			//通过rs.tojson(context)可以省服务端内存,
			//使用let data = rs.toJson(); 可以得到对象,操作更简单
			//下面等同于let data = rs.toJson().data;w.write(data);
			w.header.set("Content-type","application/json")
			w.write('{"data":')
			rs.toJson(context);
			w.write('}')
			rs.close();
		} else {
			w.write(data);
		}
		db.close();
	}catch(e){
		let data = {
			success:false,
			err:e.message
		}
		w.write(data);
	}
}

验证可以在浏览器中输入