微信小程序开发获取openid(js代码和java后端完整代码)(关于请求报400错误)
步骤
1.首先需要在微信小程序调用登录开放接口 wx.login() 获取用户登陆凭证code。
wx.login()接口说明 https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
2.向自己的服务器发送请求,并将code一起发送过去。
常用代码样例:
wx.login({
success (res) {
if (res.code) {
//发起网络请求
wx.request({
url: '自己的服务器请求接口',
data: {
code: res.code
}
})
} else {
console.log('登录失败!' + res.errMsg)
}
}
})
3.接着在自己的服务端调用auth.code2Session接口,我这里是用Java后台springboot。
auth.code2Session接口说明 https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class LoginController {
@ResponseBody
@RequestMapping("/testopenid")
public String getUserInfo(@RequestParam(name = "code") String code) throws Exception {
System.out.println("code" + code);
String url = "https://api.weixin.qq.com/sns/jscode2session";
url += "?appid=************";//自己的appid
url += "&secret=*****************";//自己的appSecret
url += "&js_code=" + code;
url += "&grant_type=authorization_code";
url += "&connect_redirect=1";
String res = null;
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// DefaultHttpClient();
HttpGet httpget = new HttpGet(url); //GET方式
CloseableHttpResponse response = null;
// 配置信息
RequestConfig requestConfig = RequestConfig.custom() // 设置连接超时时间(单位毫秒)
.setConnectTimeout(5000) // 设置请求超时时间(单位毫秒)
.setConnectionRequestTimeout(5000) // socket读写超时时间(单位毫秒)
.setSocketTimeout(5000) // 设置是否允许重定向(默认为true)
.setRedirectsEnabled(false).build(); // 将上面的配置信息 运用到这个Get请求里
httpget.setConfig(requestConfig); // 由客户端执行(发送)Get请求
response = httpClient.execute(httpget); // 从响应模型中获取响应实体
HttpEntity responseEntity = response.getEntity();
System.out.println("响应状态为:" + response.getStatusLine());
if (responseEntity != null) {
res = EntityUtils.toString(responseEntity);
System.out.println("响应内容长度为:" + responseEntity.getContentLength());
System.out.println("响应内容为:" + res);
}
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
JSONObject jo = JSON.parseObject(res);
String openid = jo.getString("openid");
System.out.println("openid-> " + openid);
return openid;
}
}
其中maven的依赖jar包为
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
这样就获得openid了。
重点
然而在开发中为了解决wx.login()异步请求转为同步请求,一般需要封装Promise对象
在微信小程序中untils包下新建一个request.js 即 /utils/request.js
import {BASE_URL} from '../config/conster.js'
//定义并导出一个发送请求的方法
export let $request = function(method,url,data,contentType){
return new Promise((resolve,reject)=>{
// 显示loading提示框
wx.showLoading({
title: '加载中',
})
//发送请求,获取分类信息
wx.request({
url:BASE_URL+url,
method,
data,
header: {
'content-type': contentType
},
// 请求数据成功的回调
success:({data})=>{
// 将请求的结果返回出去
resolve(data)
},
//请求失败
fail:(err)=>{
reject(err)
},
// 完成请求
complete:()=>{
wx.hideLoading()
}
})
})
}
//定义一个get方法
export let $get = function(url,data){
return $request('GET',url,data,'application/json')
}
//定义一个post方法
export let $post = function(url,data){
return $request('POST',url,data,'application/json')
}
// 获取openid 异步请求转同步请求
export let $getOpenId=function(){
return new Promise(function (resolve, reject) {
wx.login({
success: function (yes) {
// 发送 res.code 到后台换取 openId, sessionKey, unionId
var url = '/testopenid'
var data = {
code: yes.code
}
var contentType = 'application/x-www-form-urlencoded'
var p = $request('POST',url, data,contentType)
p.then(res => {
resolve(res)
}).catch(e => {
reject(e)
})
},
fail(e) {
console.log(e)
wx.$msg("登入失败!服务器发生错误!")
}
})
})
}
wx.$request=$request
wx.$get=$get
wx.$post=$post
wx.$getOpenId=$getOpenId
这里的 config/conster.js仅仅为(可根据需要修改)
//定义url前缀
export const BASE_URL="http://localhost:8080"
不要忘了在微信小程序项目中的app.js导入
import './utils/request.js'
关键的代码来了:
在关键的页面中加入如下代码即可
onLoad() {
this.login();
},
async login(){
let openid= await wx.$getOpenId();
console.log("创建角色的openid为:"+openid)
},
疑问:请求报400错误?
在request.js中一开始使用的是默认的请求头传入的Content-Type;结果报错,状态码是400
(ps:但我之前写的接口没有遇到这种情况,估计是springboot的锅?是我那地方的的注解有问题吗,刚学的,注解还不太熟练,就先这样改吧)
产生原因:
HTTP 400 Bad Request 表示语义有误,当前请求无法被服务器理解。因此需要请求头指定数据发送格式。
若参数组织形式为键值对,例如name=张三&sex=男&tel=5354169则需要通过表单形式提交。
若需反序列化成字符串,如{name:“张三”, sex:“男”, tel:“5354169”,},则需要通过json形式提交。
得以解决: