一、信息流小程序-GET请求案例

1.1服务端接口开发

一定要养成接口的意识,前端单打独斗出不来任何效果,必须有接口配合,写一个带有分页、关键词查询的接口:

分页接口:http://127.0.0.1:3000/info?page=1

查询接口:http://127.0.0.1:3000/search?word=李

详情接口:http://127.0.0.1:3000/xiangqing?id=2

const express = require("express");
const app = express();
const url = require("url");
const info = require("./info.js");
app.use(express.static("www")); //显示分页的明星信息
app.get("/info" , (req,res) => {
const page = url.parse(req.url , true).query.page; //得到GET请求的page参数 //提供分页的接口
res.json({
"arr" : info.slice((page-1) * 4 , page * 4)
});
}); //关键字筛选查询
app.get("/search" , (req,res) => {
//得到用户的查询词
var word = url.parse(req.url , true).query.word;
//将字符串word变为正则表达式
var wordExp = new RegExp(word);
//遍历,筛选
res.json({
"arr" : info.filter(item => wordExp.test(item.name))
});
}); //某明星详情
app.get("/xiangqing" , (req,res) => {
//得到用户的查询的明星id
var id = url.parse(req.url , true).query.id;
//遍历,筛选
res.json({
"xiangqing" : info.filter(item => item.id == id)[0]
});
})
app.listen(3000);


1.2小程序开发

学习scrioll-view容器(可滚动视图区域)和发起请求。

<scroll-view style="height:{{wH}}px;" scroll-y bindscrolltolower="tolower">
<view>乱起八早</view>
<view>乱起八早</view>
<view>乱起八早</view>
.....
</scroll-view>

bindscrolltolower表示滚动到底部的事件,但这个盒子必须有高度。

如果希望这个盒子的高度和窗口的高度一样,此时调用微信API,读取设备窗口高度。

app.js使用微信小程序的API得到屏幕的高度:

//app.js
App({
//用户首次打开小程序,触发 onLaunch函数(全局只触发一次)
onLaunch(){
var self = this;
//读取设备信息的API
wx.getSystemInfo({
success: function(res){
self.globalData.gWH = res.windowHeight; //获取窗口高度赋值给全局gWH对象
}
});
},
//全局数据
globalData : {
gWH : 0
}
});

index.js中可以获取app.js的全局数据

//每个页面可以无条件、不引包的,直接使用getApp()函数,表示调用小程序的主体
var app = getApp(); Page({
//当页面加载的时候
onLoad(){
//得到窗口的高度,globalData.gWH数据是从全局获取的
this.setData({
wH: app.globalData.gWH
});
},
//局部数据
data:{
wH: 0 //当前屏幕的高度
}
tolower(){
console.log("已经滚到底部了")
}
});

1.3页面布局

<!--index.wxml-->
<view class="container">
<scroll-view style="height:{{wH}}px" scroll-y bindscrolltolower="tolower">
  <view class="mingxing">
<view class="box" wx:for="{{mingxing}}" wx:key="{{index}}">
<view class="left">
<image src="{{baseURL}}/images/{{item.pic}}"></image>
{{item.name}}
</view>
<view class="right">
{{item.b_info}}
</view>
</view>
    </view>
</scroll-view>
</view>

index.wxss

page { background-color:#36b3ff; }
.box{
width:720rpx;display: flex;margin:10px auto;font-size: 14px;
line-height:24px;color:#333; padding:10px; background: #fff;
box-sizing:border-box; border-radius:6px; box-shadow: 1px 1px 1px rgba(0,0,0,0.5);
}
.left{flex:;}
.left image{width:180rpx; height:180rpx;}
.right{flex:;box-sizing: border-box;padding-left:10px;}

示例代码


1.4请求分页数据-显示页面效果

index.js中加载默认数据

Page({
//当页面加载的时候
onLoad(){
//得到窗口的高度,是从全局来的
this.setData({
wH: appInstance.globalData.wH
}); //核心语句:请求服务器的数据,参数page表示第几页,当前第几页就请求第几页
var self = this;
wx.request({
//请求的地址
url: 'http://127.0.0.1:3000/info?page=' + this.data.page,
//成功的回调
success({data}){
self.setData({
mingxing: [
...self.data.mingxing,
...data.arr
]
});
}
});
},
data : {
wH : 0, //当前屏幕的高度
mingxing: [], //信息流,现在是空的,等服务器返回
page : 1, //当前第几页,默认第一页
}
});

index.js下拉请求更多

var app = getApp(); 

//请求服务器上某一个页面的明星,参数page表示第几页
function queryServer(page){
//显示一个Toast,Toast就是提示文本,黑色背景的方框。
wx.showToast({
title: '正在加载更多',
icon: 'loading',
duration: 2000000 //持续时间,非常长,因为靠回调函数给它隐藏。
});
var self = this;
//核心语句,请求服务器的数据,分页请求,当前第几页就请求第几页
wx.request({
//请求的地址
url: this.data.baseURL + '/info?page=' + page,
//成功的回调
success({ data }){
//隐藏Toast
wx.hideToast();
//看一下请求的数组长度是不是0,如果是0此时就改变信号量
if(data.arr.length == 0){
self.setData({
isMore : false
});
return;
}
//如果不是0,改变值,追加数据
self.setData({
mingxing: [
...self.data.mingxing,
...data.arr
]
});
}
});
} Page({
onLoad(){
//指定queryServer函数的上下文,绑定好后,调用时上下文自动就是这里的this了
//不需要queryServer.call(this)了。
queryServer = queryServer.bind(this); //得到窗口的高度,是从全局来的
this.setData({
wH: app.globalData.wH
}); //请求第1页的数据
queryServer(1);
},
data : {
wH : 0 ,
mingxing: [],
page : 1,
baseURL:"http://127.0.0.1/3000", //基路径
isMore : true //是否还有更多?
},
tolower(){
if(this.data.isMore){
//页面数加1
this.setData({
page : this.data.page + 1
});
//下拉到底部请求更多
queryServer(this.data.page);
}
}
});

1.5关键字查询

<!--index.wxml-->
<view class="container">
<view class="s_b">
<input value="{{searchWord}}" bindconfirm="doSearch" class="s_box" type="text" />
<button bindtap='clearSearch'>×</button>
</view>
</view>

index.wxss

.s_box{ background: white;width:700rpx;margin: 0 auto;}
.s_b{ position:relative;}
.s_b button{
position: absolute; right:10px;top:; z-index:;padding:;
width:20px;height:20px;line-height: 20px;text-align: center;
}

示例代码

index.js

Page({
data : {
...
},
tolower(){
...
},
//执行查询
doSearch(event){
var self = this;
wx.request({
url: baseURL + "/search?word=" + event.detail.value ,
success({data}){
self.setData({
mingxing : data.arr
});
}
});
},
//清空查询
clearSearch(){
this.setData({
searchWord : "",
mingxing : []
});
//重新请求当前的页码,显示全部
//循环请求,比如当前页码是2,此时就要请求2、1
for(let i = 1 ; i <= this.data.page ; i++){
queryServer(i);
}
}
});


1.6点击查看详情

index.wxml

<view class="mingxing">
<view class="box" wx:for="{{mingxing}}" data-mid="{{item.id}}" bindtap='tapBox' >
.....
</view>
</view>

info.wxml详情页

<view>
<view>{{name}}</view>
<image wx:if="{{pic != ''}}" src="{{baseURL}}/images/{{pic}}"></image>
<view>
{{info}}
</view>
</view>

index.js

Page({
//点击了一个小白框,进入详情页
tapBox(event){
//通过自己的data-mid标签,知道自己是谁
var mid = event.currentTarget.dataset.mid;
//带给下一个页面
wx.navigateTo({
//通过?传参给info页面,是微信小程序的语法约定,而并不是GET请求
url: '/pages/info/info?mid=' + mid
})
}
});

info.js

//基路径
const baseURL = "http://127.0.0.1:3000"; Page({
onLoad({mid}){
var self = this;
wx.request({
url : baseURL + "/xiangqing?id=" + mid ,
success({data}){
self.setData({
name: data.xiangqing[0].name,
pic : data.xiangqing[0].pic,
info: data.xiangqing[0].info
})
}
})
},
data : {
name : "",
pic : "",
info : "",
baseURL
}
});

二、文件上传和相册API

2.1小程序和Nodejs后端

前端是小程序,后端Nodejs,用formidable来处理POST请求,上传图片。

在小程序中发起POST请求:

<!--index.wxml-->
<view class="container">
<button bindtap="fasong">按我将{a:8}这个信息用POST请求发给服务器</button>
</view>

index.js

Page({
fasong: function(){
wx.request({
//请求地址
url: 'http://127.0.0.1:3000/tijiao',
//请求类型
method : "POST" ,
//提交给服务端的数据
data : {
a : 8
},
//成功的回调函数
success : function({data}){
console.log(data.result);
}
});
}
});

后端:

const express = require("express");
const app = express();
const formidable = require("formidable"); app.post("/tijiao", (req,res)=>{
var form = new formidable.IncomingForm();
form.parse(req, (err, data) => {
console.log(data);
res.json({result:"ok"});
});
}); app.listen(3000);

示例代码


2.2 图片的上传

在微信中是两个事:

第一:调用wx.chooseImage()这个API,让用户选择一个图片文件或者拍照;

第二:调用wx.uploadFile()这个API,来传输文件。

从本地相册选择图片或使用相机拍照API:

wx.chooseImage();

上传文件的API:

wx.uploadFile();

<!--index.wxml-->
<view class="container">
<button bindtap="chooseImg">选择图片</button>
</view>

前端代码index.js:

Page({
chooseImg(){
//选择图片或者进行拍照
wx.chooseImage({
count : 1, //只能选择1张
//选择图片成功之后做的事情
success({tempFilePaths}){
wx.uploadFile({
url : "http://127.0.0.1:3000/tijiao" , //上传地址
filePath: tempFilePaths[0], //要上传的文件,只有1张图片也是数组,所以[0]
name: "tupian", //key
success({data}){
wx.showToast({
title: "上传成功!"
});
}
});
}
});
}
});

后端formidable可以处理图片的上传,只需要加一句话:

const express = require("express");
const app = express();
const formidable = require("formidable"); app.post("/tijiao", (req,res)=>{
var form = new formidable.IncomingForm();
form.uploadDir = "./uploads"; //设置图片的保存路径
form.keepExtensions = true; //保留拓展名 form.parse(req, (err, fileds, file)=>{
res.json({result: "ok"});
});
}); app.listen(3000);

开启下拉刷新,在需要下拉刷新的页面中index.json中添加:

{
"enablePullDownRefresh" : true
}
<!--index.wxml-->
<view class="container">
<button bindtap="chooseImg">选择图片</button>
<view wx:for="{{imgList}}" wx:key="{{index}}">
<image mode="center" src="http://127.0.0.1:3000/uploads/{{item}}"></image>
</view>
</view>

后端app.js

const express = require("express");
const app = express();
const formidable = require("formidable");
const fs = require("fs"); //静态化图片目录
app.use("/uploads" , express.static("uploads")); //处理用户的提交
app.post("/tijiao" , (req,res) => {
var form = new formidable.IncomingForm();
form.uploadDir = "./uploads"; //设置图片的保存路径
form.keepExtensions = true; //保留拓展名 form.parse(req , (err , fileds , files) => {
//将上传文件改名为现在的时间戳,就是1970年1月1日到现在的毫秒数
var date = Date.parse(new Date());
   var ext = path.extname(files.tupian.path); //获取文件扩展名
//改名
fs.rename(`./${files.tupian.path}`, `./uploads/${date}${ext}`, function(){
res.json({result : "ok"});
});
});
}); //列出所有文件的清单
app.get("/list" , (req,res)=>{
fs.readdir("./uploads", (err, files) => {
res.json({ imgList: files.reverse()});
});
}); app.listen(3000);

index.js

Page({
xuantu(){
...
},
//显示所有已经上传的图片
onLoad(){
var self = this;
wx.request({
url: "http://127.0.0.1:3000/list",
success({data}){
self.setData({
imgList: data.imgList
})
}
});
},
//当下拉刷新的时候
onPullDownRefresh(){
var self = this;
wx.request({
url: "http://127.0.0.1:3000/list",
success({data}){
self.setData({
imgList: data.imgList
})
}
});
}
});

2.3获取微信用户信息

//得到app本身,为什么要得到,因为一会就能使用app.globalData.userInfo
const app = getApp(); Page({
...
addPics(){
...
},
//*************这里面的代码是从HelloWorld案例抄的 start*************
onLoad: function () {
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
})
} else if (this.data.canIUse){
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
app.userInfoReadyCallback = res => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
} else {
//在没有 open-type=getUserInfo 版本的兼容处理
wx.getUserInfo({
success: res => {
app.globalData.userInfo = res.userInfo;
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
});
}
})
}
},
getUserInfo: function(e) {
app.globalData.userInfo = e.detail.userInfo;
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
});
}
//*************这里面的代码是从Hello World案例抄的 end*************
})

示例代码


三、Nodejs配置https

首先,需要申请SSL证书,证书可以在阿里云、腾讯云、宝塔等平台申请,申请成功后会提供SSL证书下载地址,下载好SSL证书会看见一个压缩包,里面包含很多版本的证书文件(IIS、Apache、Nginx、Tomcat)等,Nodejs服务端采用Nginx版本即可,里面有两个文件分别是:.key和.pem文件。

将文件放在你的Node项目中的某个文件夹中,这里我放在根目录的ssl文件夹中。

然后写以下Node代码即可开启https

注意:要修改自己的key和pem文件路径和名称

//使用node自带的https模块开启https服务
var https = require("https"); //读取https配置文件
//读取https配置
var httpsOption = {
key : fs.readFileSync("./ssl/0_iqd.webqianduan.cn.key"),
cert: fs.readFileSync("./ssl/1_iqd.webqianduan.cn_bundle.pem")
} //监听端口
http.createServer(app).listen(80);
https.createServer(httpsOption, app).listen(443);

前端笔记之微信小程序(三)GET请求案例&文件上传和相册API&配置https的更多相关文章

  1. 前端笔记之微信小程序(二){{}}插值和MVVM模式&数据双向绑定&指令&API

    一.双花括号{{}}插值和MVVM模式 1.1 体会{{}}插值 index.wxml的标签不是html的那些标签,这里的view就是div. {{}}这样的插值写法,叫做mustache语法.mus ...

  2. 前端笔记之微信小程序(四)WebSocket&Socket.io&摇一摇案例&地图|地理位置

    一.WebSocket概述 http://www.ruanyifeng.com/blog/2017/05/websocket.html Workerman一款开源高性能异步PHP socket即时通讯 ...

  3. 前端笔记之微信小程序(一)初识微信小程序&WXSS与CSS|WXML与HTML的差异&像素和DPR

    一.小程序概述 2017 年 1 月 9 日小程序正式上线,腾讯开放了个人开发者开发小程序,小程序从此就开始火爆,这一年,小程序狂揽 4 亿用户.1.7 亿的日常活跃,上线 58 万个.这是一个巨大的 ...

  4. 微信小程序里如何用阿里云上传视频,图片。。

    纯手写,踩了半天多的坑干出来了... 网上也有对于阿里云如何在微信小程序里使用,但是很不全,包括阿里云文档的最佳实践里. 话不多说上代码了. upvideo(){ var aliOssParams = ...

  5. 转:【微信小程序】 微信小程序-拍照或选择图片并上传文件

    调用拍照API:https://mp.weixin.qq.com/debug/wxadoc/dev/api/media-picture.html?t=20161222#wxchooseimageobj ...

  6. [转]微信小程序开发(二)图片上传+服务端接收

    本文转自:http://blog.csdn.net/sk719887916/article/details/54312573 文/YXJ 地址:http://blog.csdn.net/sk71988 ...

  7. 入坑微信小程序必经之路(六)图片上传服务器——WebSercice接口

    wxml文件 <view class="weui-uploader"> <view class="img-v weui-uploader__bd&quo ...

  8. 微信小程序知识总结及案例集锦

    微信小程序知识总结及案例集锦 微信小程序的发展会和微信公众号一样,在某个时间点爆发 学习路径 微信小程序最好的教程肯定是官方的文档啦,点击这里直达 微信官方文档 认真跟着文档看一遍,相信有vue前端经 ...

  9. 微信小程序电商实战-首页(上)

    嗨,大家好!经过近两周的精心准备终于开始微信小程序电商实战之路喽.那么最终会做成什么样呢?当然可以肯定不会只做一个静态demo哦,先把我们小程序电商实战的整体架构发出来晒一下,请看下图:   架构图. ...

随机推荐

  1. 利用MAT分析JVM内存问题,从入门到精通(二)

    上一篇文章MAT入门到精通(一)介绍了MAT的使用场景和基本概念,这篇文章开始介绍MAT的基本功能,后面还有两篇,一篇是MAT的高级功能,另一篇是MAT实战案例分析. 三.欢迎页 使用MAT打开一个h ...

  2. BZOJ 1026:windy数(数位DP)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1026 1026: [SCOI2009]windy数 Time Limit: 1 Sec  Memor ...

  3. redis 基础数据结构实现

    参考文献 redis数据结构分析 Skip List(跳跃表)原理详解 redis 源码分析之内存布局 Redis 基础数据结构与对象 Redis设计与实现-第7章-压缩列表 在redis中构建了自己 ...

  4. JPA自定义实体的id

    背景:继上一篇文章,已经实现客户端数据库数据,存入服务器,但是,两张表的id不一样,应该是id设置自增了,所以虽然从客户端查出的实体带id,但是存入服务器时id被抹掉,按照服务端表的id序号向上自增, ...

  5. c++最大公约数

    C++辗转相除法求出最大公因数 样例输入 6 9 样例输出 3 程序 #include <stdio.h> using namespace std; int gcd(int m,int n ...

  6. ZigBee按键中断

    何为按键中断? 在了解按键中断之前,我们先来了解一下什么是中断?中断就是程序执行当前代码,当前任务的时候: 突然有自身函数或外部的影响,而使程序执行到别的任务再回来. 举个栗子: 当你在做饭的时候,电 ...

  7. ZigBee按键查询实践

    按键查询 即硬件上电后,程序开始运行,当检测到按键按下,触发按键语句,执行按键触发的事件: 玩单片机需要清楚两件东西,第一个是单片机的电路图,另一个则是单片机的寄存器: CC2530是51的升级版,我 ...

  8. python 3.5学习笔记(第五章)

    本章内容 1.什么是模块 2.模块的导入方法 3.搜索路径 4.重要标准库 一.什么是模块 1.模块本质上是一个以.py 结尾的python文件,包含了python对象定义和python语句. 2.模 ...

  9. UNICODE环境下读写txt文件操作

    内容转载自http://blog.sina.com.cn/s/blog_5d2bad130100t0x9.html UNICODE环境下读写txt文件操作 (2011-07-26 17:40:05) ...

  10. E11000 duplicate key error index

    E11000 duplicate key error index mongodb插入报错,重复主键问题,有唯一键值重复 一般使用collection.insertOne(doc);插入一条已存在主键的 ...