一、信息流小程序-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

  1. const express = require("express");
  2. const app = express();
  3. const url = require("url");
  4. const info = require("./info.js");
  5. app.use(express.static("www"));
  6.  
  7. //显示分页的明星信息
  8. app.get("/info" , (req,res) => {
  9. const page = url.parse(req.url , true).query.page; //得到GET请求的page参数
  10.  
  11. //提供分页的接口
  12. res.json({
  13. "arr" : info.slice((page-1) * 4 , page * 4)
  14. });
  15. });
  16.  
  17. //关键字筛选查询
  18. app.get("/search" , (req,res) => {
  19. //得到用户的查询词
  20. var word = url.parse(req.url , true).query.word;
  21. //将字符串word变为正则表达式
  22. var wordExp = new RegExp(word);
  23. //遍历,筛选
  24. res.json({
  25. "arr" : info.filter(item => wordExp.test(item.name))
  26. });
  27. });
  28.  
  29. //某明星详情
  30. app.get("/xiangqing" , (req,res) => {
  31. //得到用户的查询的明星id
  32. var id = url.parse(req.url , true).query.id;
  33. //遍历,筛选
  34. res.json({
  35. "xiangqing" : info.filter(item => item.id == id)[0]
  36. });
  37. })
  38. app.listen(3000);


1.2小程序开发

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

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

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

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

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

  1. //app.js
  2. App({
  3. //用户首次打开小程序,触发 onLaunch函数(全局只触发一次)
  4. onLaunch(){
  5. var self = this;
  6. //读取设备信息的API
  7. wx.getSystemInfo({
  8. success: function(res){
  9. self.globalData.gWH = res.windowHeight; //获取窗口高度赋值给全局gWH对象
  10. }
  11. });
  12. },
  13. //全局数据
  14. globalData : {
  15. gWH : 0
  16. }
  17. });

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

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

1.3页面布局

  1. <!--index.wxml-->
  2. <view class="container">
  3. <scroll-view style="height:{{wH}}px" scroll-y bindscrolltolower="tolower">
  4.   <view class="mingxing">
  5. <view class="box" wx:for="{{mingxing}}" wx:key="{{index}}">
  6. <view class="left">
  7. <image src="{{baseURL}}/images/{{item.pic}}"></image>
  8. {{item.name}}
  9. </view>
  10. <view class="right">
  11. {{item.b_info}}
  12. </view>
  13. </view>
  14.     </view>
  15. </scroll-view>
  16. </view>

index.wxss

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

示例代码


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

index.js中加载默认数据

  1. Page({
  2. //当页面加载的时候
  3. onLoad(){
  4. //得到窗口的高度,是从全局来的
  5. this.setData({
  6. wH: appInstance.globalData.wH
  7. });
  8.  
  9. //核心语句:请求服务器的数据,参数page表示第几页,当前第几页就请求第几页
  10. var self = this;
  11. wx.request({
  12. //请求的地址
  13. url: 'http://127.0.0.1:3000/info?page=' + this.data.page,
  14. //成功的回调
  15. success({data}){
  16. self.setData({
  17. mingxing: [
  18. ...self.data.mingxing,
  19. ...data.arr
  20. ]
  21. });
  22. }
  23. });
  24. },
  25. data : {
  26. wH : 0, //当前屏幕的高度
  27. mingxing: [], //信息流,现在是空的,等服务器返回
  28. page : 1, //当前第几页,默认第一页
  29. }
  30. });

index.js下拉请求更多

  1. var app = getApp();
  2.  
  3. //请求服务器上某一个页面的明星,参数page表示第几页
  4. function queryServer(page){
  5. //显示一个Toast,Toast就是提示文本,黑色背景的方框。
  6. wx.showToast({
  7. title: '正在加载更多',
  8. icon: 'loading',
  9. duration: 2000000 //持续时间,非常长,因为靠回调函数给它隐藏。
  10. });
  11. var self = this;
  12. //核心语句,请求服务器的数据,分页请求,当前第几页就请求第几页
  13. wx.request({
  14. //请求的地址
  15. url: this.data.baseURL + '/info?page=' + page,
  16. //成功的回调
  17. success({ data }){
  18. //隐藏Toast
  19. wx.hideToast();
  20. //看一下请求的数组长度是不是0,如果是0此时就改变信号量
  21. if(data.arr.length == 0){
  22. self.setData({
  23. isMore : false
  24. });
  25. return;
  26. }
  27. //如果不是0,改变值,追加数据
  28. self.setData({
  29. mingxing: [
  30. ...self.data.mingxing,
  31. ...data.arr
  32. ]
  33. });
  34. }
  35. });
  36. }
  37.  
  38. Page({
  39. onLoad(){
  40. //指定queryServer函数的上下文,绑定好后,调用时上下文自动就是这里的this了
  41. //不需要queryServer.call(this)了。
  42. queryServer = queryServer.bind(this);
  43.  
  44. //得到窗口的高度,是从全局来的
  45. this.setData({
  46. wH: app.globalData.wH
  47. });
  48.  
  49. //请求第1页的数据
  50. queryServer(1);
  51. },
  52. data : {
  53. wH : 0 ,
  54. mingxing: [],
  55. page : 1,
  56. baseURL:"http://127.0.0.1/3000", //基路径
  57. isMore : true //是否还有更多?
  58. },
  59. tolower(){
  60. if(this.data.isMore){
  61. //页面数加1
  62. this.setData({
  63. page : this.data.page + 1
  64. });
  65. //下拉到底部请求更多
  66. queryServer(this.data.page);
  67. }
  68. }
  69. });

1.5关键字查询

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

index.wxss

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

示例代码

index.js

  1. Page({
  2. data : {
  3. ...
  4. },
  5. tolower(){
  6. ...
  7. },
  8. //执行查询
  9. doSearch(event){
  10. var self = this;
  11. wx.request({
  12. url: baseURL + "/search?word=" + event.detail.value ,
  13. success({data}){
  14. self.setData({
  15. mingxing : data.arr
  16. });
  17. }
  18. });
  19. },
  20. //清空查询
  21. clearSearch(){
  22. this.setData({
  23. searchWord : "",
  24. mingxing : []
  25. });
  26. //重新请求当前的页码,显示全部
  27. //循环请求,比如当前页码是2,此时就要请求2、1
  28. for(let i = 1 ; i <= this.data.page ; i++){
  29. queryServer(i);
  30. }
  31. }
  32. });


1.6点击查看详情

index.wxml

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

info.wxml详情页

  1. <view>
  2. <view>{{name}}</view>
  3. <image wx:if="{{pic != ''}}" src="{{baseURL}}/images/{{pic}}"></image>
  4. <view>
  5. {{info}}
  6. </view>
  7. </view>

index.js

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

info.js

  1. //基路径
  2. const baseURL = "http://127.0.0.1:3000";
  3.  
  4. Page({
  5. onLoad({mid}){
  6. var self = this;
  7. wx.request({
  8. url : baseURL + "/xiangqing?id=" + mid ,
  9. success({data}){
  10. self.setData({
  11. name: data.xiangqing[0].name,
  12. pic : data.xiangqing[0].pic,
  13. info: data.xiangqing[0].info
  14. })
  15. }
  16. })
  17. },
  18. data : {
  19. name : "",
  20. pic : "",
  21. info : "",
  22. baseURL
  23. }
  24. });

二、文件上传和相册API

2.1小程序和Nodejs后端

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

在小程序中发起POST请求:

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

index.js

  1. Page({
  2. fasong: function(){
  3. wx.request({
  4. //请求地址
  5. url: 'http://127.0.0.1:3000/tijiao',
  6. //请求类型
  7. method : "POST" ,
  8. //提交给服务端的数据
  9. data : {
  10. a : 8
  11. },
  12. //成功的回调函数
  13. success : function({data}){
  14. console.log(data.result);
  15. }
  16. });
  17. }
  18. });

后端:

  1. const express = require("express");
  2. const app = express();
  3. const formidable = require("formidable");
  4.  
  5. app.post("/tijiao", (req,res)=>{
  6. var form = new formidable.IncomingForm();
  7. form.parse(req, (err, data) => {
  8. console.log(data);
  9. res.json({result:"ok"});
  10. });
  11. });
  12.  
  13. app.listen(3000);

示例代码


2.2 图片的上传

在微信中是两个事:

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

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

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

  1. wx.chooseImage();

上传文件的API:

  1. wx.uploadFile();

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

前端代码index.js:

  1. Page({
  2. chooseImg(){
  3. //选择图片或者进行拍照
  4. wx.chooseImage({
  5. count : 1, //只能选择1张
  6. //选择图片成功之后做的事情
  7. success({tempFilePaths}){
  8. wx.uploadFile({
  9. url : "http://127.0.0.1:3000/tijiao" , //上传地址
  10. filePath: tempFilePaths[0], //要上传的文件,只有1张图片也是数组,所以[0]
  11. name: "tupian", //key
  12. success({data}){
  13. wx.showToast({
  14. title: "上传成功!"
  15. });
  16. }
  17. });
  18. }
  19. });
  20. }
  21. });

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

  1. const express = require("express");
  2. const app = express();
  3. const formidable = require("formidable");
  4.  
  5. app.post("/tijiao", (req,res)=>{
  6. var form = new formidable.IncomingForm();
  7. form.uploadDir = "./uploads"; //设置图片的保存路径
  8. form.keepExtensions = true; //保留拓展名
  9.  
  10. form.parse(req, (err, fileds, file)=>{
  11. res.json({result: "ok"});
  12. });
  13. });
  14.  
  15. app.listen(3000);

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

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

后端app.js

  1. const express = require("express");
  2. const app = express();
  3. const formidable = require("formidable");
  4. const fs = require("fs");
  5.  
  6. //静态化图片目录
  7. app.use("/uploads" , express.static("uploads"));
  8.  
  9. //处理用户的提交
  10. app.post("/tijiao" , (req,res) => {
  11. var form = new formidable.IncomingForm();
  12. form.uploadDir = "./uploads"; //设置图片的保存路径
  13. form.keepExtensions = true; //保留拓展名
  14.  
  15. form.parse(req , (err , fileds , files) => {
  16. //将上传文件改名为现在的时间戳,就是1970年1月1日到现在的毫秒数
  17. var date = Date.parse(new Date());
  18.    var ext = path.extname(files.tupian.path); //获取文件扩展名
  19. //改名
  20. fs.rename(`./${files.tupian.path}`, `./uploads/${date}${ext}`, function(){
  21. res.json({result : "ok"});
  22. });
  23. });
  24. });
  25.  
  26. //列出所有文件的清单
  27. app.get("/list" , (req,res)=>{
  28. fs.readdir("./uploads", (err, files) => {
  29. res.json({ imgList: files.reverse()});
  30. });
  31. });
  32.  
  33. app.listen(3000);

index.js

  1. Page({
  2. xuantu(){
  3. ...
  4. },
  5. //显示所有已经上传的图片
  6. onLoad(){
  7. var self = this;
  8. wx.request({
  9. url: "http://127.0.0.1:3000/list",
  10. success({data}){
  11. self.setData({
  12. imgList: data.imgList
  13. })
  14. }
  15. });
  16. },
  17. //当下拉刷新的时候
  18. onPullDownRefresh(){
  19. var self = this;
  20. wx.request({
  21. url: "http://127.0.0.1:3000/list",
  22. success({data}){
  23. self.setData({
  24. imgList: data.imgList
  25. })
  26. }
  27. });
  28. }
  29. });

2.3获取微信用户信息

  1. //得到app本身,为什么要得到,因为一会就能使用app.globalData.userInfo
  2. const app = getApp();
  3.  
  4. Page({
  5. ...
  6. addPics(){
  7. ...
  8. },
  9. //*************这里面的代码是从HelloWorld案例抄的 start*************
  10. onLoad: function () {
  11. if (app.globalData.userInfo) {
  12. this.setData({
  13. userInfo: app.globalData.userInfo,
  14. hasUserInfo: true
  15. })
  16. } else if (this.data.canIUse){
  17. // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
  18. // 所以此处加入 callback 以防止这种情况
  19. app.userInfoReadyCallback = res => {
  20. this.setData({
  21. userInfo: res.userInfo,
  22. hasUserInfo: true
  23. })
  24. }
  25. } else {
  26. //在没有 open-type=getUserInfo 版本的兼容处理
  27. wx.getUserInfo({
  28. success: res => {
  29. app.globalData.userInfo = res.userInfo;
  30. this.setData({
  31. userInfo: res.userInfo,
  32. hasUserInfo: true
  33. });
  34. }
  35. })
  36. }
  37. },
  38. getUserInfo: function(e) {
  39. app.globalData.userInfo = e.detail.userInfo;
  40. this.setData({
  41. userInfo: e.detail.userInfo,
  42. hasUserInfo: true
  43. });
  44. }
  45. //*************这里面的代码是从Hello World案例抄的 end*************
  46. })

示例代码


三、Nodejs配置https

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

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

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

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

  1. //使用node自带的https模块开启https服务
  2. var https = require("https");
  3.  
  4. //读取https配置文件
  5. //读取https配置
  6. var httpsOption = {
  7. key : fs.readFileSync("./ssl/0_iqd.webqianduan.cn.key"),
  8. cert: fs.readFileSync("./ssl/1_iqd.webqianduan.cn_bundle.pem")
  9. }
  10.  
  11. //监听端口
  12. http.createServer(app).listen(80);
  13. 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. 并发编程-concurrent指南-原子操作类-AtomicLong

    可以用原子方式更新的 long 值.有关原子变量属性的描述,请参阅 java.util.concurrent.atomic 包规范.AtomicLong 可用在应用程序中(如以原子方式增加的序列号), ...

  2. BZOJ 1878:[SDOI2009]HH的项链(莫队算法)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1878 题意:…… 思路:比上题还简单很多.数字很小,开一个数组哈希记录出现次数(记得数组要开1e6) ...

  3. abview查找范例时说 NI服务器未定位 这是怎么回事?

    NI服务定位器未运行在使用labview查找范例时,出现“NI服务定位器未运行”的对话框,而后不能够打开范例.有以下方法.方法一:是防火墙服务禁用造成的,在防火墙规则里面找,把和NI相关的都允许. 方 ...

  4. 利用Docker搭建Redis集群

    Redis集群搭建 运行Redis镜像 分别使用以下命令启动3个Redis docker run --name redis-6379 -p 6379:6379 -d hub.c.163.com/lib ...

  5. Git命令行之快速入门

    从头开始创建一个版本库,添加一些内容,然后管理一些修订版本. 有两种建立 Git版本库 的基础技术.第一:从头开始创建,用现有的内容填充它.第二:可以克隆一个已有的版本库.这里选择从一个空的版本库开始 ...

  6. 爬虫的盗亦有道Robots协议

    爬虫的规定 Robots协议 网站开发者对于网络爬虫的规范的公告,你可以不遵守可能存在法律风险,但尽量去遵守 Robots协议:在网页的根目录+robots.txt Robots协议的基本语法: #注 ...

  7. [leetcode] 300. Longest Increasing Subsequence (Medium)

    题意: 求最长增长的子序列的长度. 思路: 利用DP存取以i作为最大点的子序列长度. Runtime: 20 ms, faster than 35.21% of C++ online submissi ...

  8. 一个简单的JS倒计时

    看到很多商城都是抢购倒计时的功能,今天闲来无事做了个倒计时.全当学习JS. 主要思路:主要用到Date对象,声明一个变量获取当前时间,在声明一个变量获取结束时间,结束时间-当前时间=剩余时间(倒计时) ...

  9. python函数基础-参数-返回值-注释-01

    什么是函数 函数就是有特定功能的工具 # python中有内置函数(python解释器预先封装好的)与自定义函数(用户自定义封装的)之分 为什么要用函数 # 可以减少代码冗余,增加代码复用性 # 使代 ...

  10. maven install时跳过测试

    xl_echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!! - ...