小程序关于请求接口302重定向处理方法

业务场景描述

后端提供了一个接口,正常post请求,但是此接口返回结果是 302 , 页面自动重定向到 结果页面。
如下图所示,我们请求到这个 302 接口之后其实是希望直接打开下面那条 200 请求的 index.html 页面。
下图是在浏览器中测试的 ajax 请求,那么此时我们需要在小程序中实现请求接口直接打开页面的功能。
在这里插入图片描述

预期目标

在这里插入图片描述

第一次尝试(失败)

我们知道的是,小程序中只能使用人家提供的 API ,不能自己写,所有的封装和变换都是在 wx.request 这个 API 的基础上,底层是不能变的。

所以要发起请求我们只能使用 wx.request ,看代码:

const data = {
      pf: '2',
      appId: 'mgszwfwlzt',
      sign: this.data.sign,
      taskId: this.data.qlsxBasicInfo.TaskCode,
      timestamp: this.data.timeStamp,
    }
    wx.request({
      url: 'https://*********/bjpjList.do',
      header: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      data,
      method: 'POST',
      success: function(response) {
        console.log(response)
      }
    })

按照我们平时请求接口的写法,我们请求一下这个 bjpjList.do 的接口,看下 network 监听到了什么:

在这里插入图片描述

在小程序中我们其实也监听到了 bjpjList.do 的请求,但是一闪而过,立马变成了 index.html 的请求,返回结果也直接是我们 index.html 的代码

在这里插入图片描述

百度了很多说可以在 response.header 里面获取到 location, 也就是 302 重定向 index.html 的地址,我们展开 response 看看到底有没有

在这里插入图片描述
可以看出,小程序人家直接帮我们请求重定向之后的页面了,没给我们权利去监听这个重定向的地址,感觉没戏了,可以页面地址看得到拿不到,那我不信,打开官网看看官网提供的 API

在这里插入图片描述
发现还有别的 API 我们打开看看 onHeadersReceived

这个 API 官网的解释是监听 HTTP Rresponse Header 事件

这不就是我们要的么,监听我们发起 HTTP 请求的头部,去读取重定向之后的地址

我们接着写,代码如下:

const data = {
      pf: '2',
      appId: 'mgszwfwlzt',
      sign: this.data.sign,
      taskId: this.data.qlsxBasicInfo.TaskCode,
      timestamp: this.data.timeStamp,
    }
    wx.request({
      url: 'https://********/bjpjList.do',
      header: {
        'content-type': 'application/x-www-form-urlencoded'
      },
      data,
      method: 'POST',
      success: function(response) {
        console.log(response)
      }
    }).onHeadersReceived(res => {
      if (res.header.location) {
        wx.hideLoading()
        this.setData({
          pageLink: res.header.location
        })
      }
    })

我们发现开发工具上还是 重定向之后的头部信息,不满足情况

在这里插入图片描述

可以鉴于有时候真机测试和开发工具的测试结果是不一样的,我们使用真机测试一下(我使用的安卓手机)

在这里插入图片描述

可以看到开发工具上没有直接跳转,而且监听到了两次 onHeadersReceived 事件:

在这里插入图片描述
在这里插入图片描述
图中可知 第一次监听事件其实获取到了 这个 location 地址,那我们就写了上面的代码,直接使用 webview 标签跳转就好了

安卓手机全部Ok没问题,上体验版之后,苹果手机一律打不开,每次苹果手机都作妖都习惯了,我们换个苹果在测试一下

使用 iphone 6s Plus 测试,发现我们的 onHeadersReceived 事件和我们开发工具上的情况是一样的,只能监听到一次,还是获取不到 location 地址

我们想投机取巧的方式失败

PS:至于百度说把请求方式换成 HEAD 这样的方式,如果你后端只支持 POST 请求方式,请求都不会成功,或者你和后台能商量修改当然最好。这里我们没得权限修改后端,继续自己想办法!

第二次尝试(成功)

这里其实你会发现小程序里面的 API 已经没有什么可用的了,那我们只能想别的办法。

这种方式是使用跳转 H5 的方式,用浏览器去处理 302 请求自动跳转

在这里插入图片描述

由上图中看出,我们已经将请求接口的功能交给了 h5 的空白页面,提交请求后,直接跳转结果页面,这是浏览器默认的

也就是说小程序对 302 重定向的方式 无能为力

因为页面默认是 form 表单提交,提交成功后默认跳转,看一下大致代码

在这里插入图片描述
我们读取到 小程序传入 H5 页面的参数并将字符串转换成对象形式

然后使用了关键的 form.submit() 提交表单

在这里插入图片描述

PS:如果不使用 form.submit() 方式,使用 ajax 请求还是不能自动跳转

把 h5 页面放到服务器上,带出网络地址

然后把小程序中的跳转地址修改

在这里插入图片描述
如图所示,记得加入 业务域名

到这里问题就完美解决了,这里是我们的页面加载很慢的问题,不是代码问题,不用担心

在这里插入图片描述

如果大家有更好的方式也可以直接私信我!感谢!

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在Java中实现微信小程序登录拦截器,你需要完成以下步骤: 1. 编写拦截器类,实现 HandlerInterceptor 接口。 2. 在拦截器类中的 preHandle 方法中,获取请求参数中的 code 和 encryptedData 字段。 3. 使用 code 字段向微信服务器发送请求,获取 session_key 和 openid。 4. 使用 session_key 和 encryptedData 字段解密用户信息,获取用户的 openid 和其他信息。 5. 将用户信息存储在会话中,以便后续请求中使用。 6. 如果用户未登录或登录信息已过期,将其重定向到登录页面。 下面是一个示例代码,展示如何实现微信小程序登录拦截器: ``` public class WechatLoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { String code = request.getParameter("code"); String encryptedData = request.getParameter("encryptedData"); // 发送请求获取 session_key 和 openid String sessionKey = getSessionKey(code); String openid = getOpenid(sessionKey); // 解密用户信息 String userInfo = decryptUserInfo(sessionKey, encryptedData); // 存储用户信息到会话中 request.getSession().setAttribute("openid", openid); request.getSession().setAttribute("userInfo", userInfo); // 判断用户是否已登录 boolean isLogin = checkLoginStatus(request); if (isLogin) { return true; } else { // 重定向到登录页面 response.sendRedirect("/login"); return false; } } private String getSessionKey(String code) { // 发送请求获取 session_key // ... } private String getOpenid(String sessionKey) { // 发送请求获取 openid // ... } private String decryptUserInfo(String sessionKey, String encryptedData) { // 解密用户信息 // ... } private boolean checkLoginStatus(HttpServletRequest request) { // 判断用户是否已登录 // ... } } ``` 在拦截器类中,你需要实现 getSessionKey、getOpenid、decryptUserInfo 和 checkLoginStatus 方法,以完成微信登录的操作。在 preHandle 方法中,你需要判断用户是否已登录,并根据需要重定向到登录页面。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值