Typecho前台登陆的正确打开方式

2022-5-16 18:45| 发布者: Hocassian| 查看: 64| 评论: 0|原作者: 三无计划的博客

摘要:
C:\Users\Administrator\Downloads\2019-10-13-21-42-29-124521726142699-无文字 三无计划-采集的数据-后羿采集器.html

发布时间

Jun 23, 2019

标题链接

https://blog.imalan.cn/archives/387/

标题

Typecho 前台登陆的正确打开方式

word-count

+ 893 字

导语

博客现已支持夜间模式切换、字体切换、字号调整了,另一项比较重要的功能就是本文要说的前台登陆。

正文

快点击屏幕顶部或者右下角的 体验一下新的外观设置面板吧~面板底部靠左的按钮即可用于前台登陆。

现在许多主题都使用 PJAX 或者其他技术让整个站点变成了一个单页应用,主要目的是让浏览体验更加连贯。但是 Type­cho 毕竟是比较传统的程序,某些 API 是缺乏的(Word­press 有 REST API),许多东西还是要靠登陆后台完成,例如回复读者评论,总免不了要去登陆页面溜达一圈,有点烦人;为了安全性,也不建议将后台路径暴露出来。

我去年写了一篇 Typecho 前台登录、Gist 页面上线,在页面上仿照 Type­cho 的 ad­min.php 添加一个 form 来实现前台登陆,效果不错。但是后来发现 PJAX 切换页面后就不行了,需要刷新一下才能登陆…… 不过也没管了。

在 VOID 进入第三版之际我想把这个功能加回来,研究后发现其实很简单……Type­cho 给每个页面分配的 logi­n­Ac­tion 都不同,因此如果希望在某页面登陆后跳转回当前页面,logi­n­Ac­tion 需要与页面链接、ref­erer 相匹配。

如果 PJAX 的容器不包含 form 元素,那么切换页面后 logi­n­Ac­tion 与 ref­erer 都还是老的,因此处理时只需要检测页面是否经过了 PJAX 跳转,如果跳转了,那么这两个参数就要更新一下。更新也很简单,发起一个 AJAX 后台请求一下当前页面,从返回的 HTML 里把新的 logi­n­Ac­tion 挑出来,并且把 ref­erer 设置成当前页面。

以下是简单的代码说明。form 元素依旧与之前相同,并加上一个 id 方便区分:

<form action="<?php $this->options->loginAction(); ?>" id="login-form" method="post" name="login" role="form">
  <input type="text" name="name" autocomplete="username" placeholder="请输入用户名" required/>
  <input type="password" name="password" autocomplete="current-password" placeholder="请输入密码" required/>
  <input type="hidden" name="referer" value="<?php
    if($this->is('index')) $this->options->siteUrl();
    else $this->permalink();
  ?>">

  <button class="btn btn-normal" type="submit">登录</button>
</form>

前台在 PJAX 完成时添加一个标志记录一下:

$(document).on('pjax:complete', function () {
  $('form#login-form').addClass('need-refresh');
});

然后在合适的时候(比如唤起登陆框时)执行以下更新代码:

if ($('#login-form').hasClass('need-refresh')) {
  $.get({
    url: location.href,
    success: function (data) {
      $('form#login-form').attr('action', $(data).find('form#login-form').attr('action'));
      $('form#login-form').removeClass('need-refresh');
    },
    error: function () {
      alert('请求登陆参数错误。请在刷新后尝试登陆。');
      setTimeout(function () {
        location.reload();
      }, 1000);
    }
  });
}

当然你可以写一些 CSS 来提示用户当前在请求新的登陆参数,需要稍等一下。比如:

form#login-form.need-refresh {
  opacity: 0.5;
}

上面的方法每次请求都要重载整个页面,给服务端带来了额外负担。经评论区提示,可改用 POST 请求当前页面地址,并在后端针对响应,免去执行其他无用代码。例如:

$.ajax({
  type: 'POST',
  url: window.location.href,
  data: {action: 'getLoginAction'},
  success: function (data) {
    $('form#loggin-form').attr('action', data);
    $('form#loggin-form').removeClass('need-refresh');
  },
  error: function () {
    alert('请求登陆参数错误。请在刷新后尝试登陆。');
    setTimeout(function () {
      location.reload();
    }, 1000);
  }
});

注意这里不要使用 GET 请求,因为参数不同生成的 logi­n­Ac­tion 也不同,GET 请求不方便随意带参数。在后端主题代码的入口处(例如 header.php 或者 head.php 顶部)添加:

if (isset($_POST['action'])) {
  if ($_POST['action'] == 'getLoginAction') {
    echo $this->options->loginAction;
    exit;
  }
}

这也勉强算是 VOID 开发笔记的一篇吧…… 就酱。

作者

熊猫小 A


路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部