WP DEVELOP

EP092. “REST API 删除请求与 Nonce 身份验证”

首页 WordPress 开发课程 MY NOTES 前端功能 · EP092
约 9 分钟· #EP092#MY NOTES 前端功能
🔒 登录后可标记已读

接上一讲,把删除按钮真正接上 WordPress REST API。因为 note 文章类型注册时已经开了 show_in_rest,所以自动拥有标准 REST 端点,直接对 wp-json/wp/v2/note/{ID} 发送 DELETE 类型的请求即可删除。这里第一次用到 $.ajax() 而不是 $.getJSON()(后者只能发 GET)。第一次尝试会被 WordPress 拒绝(401 Unauthorized),因为请求没有带上身份凭证——WordPress REST API 默认不信任任何未经验证的写操作。解法是用 Nonce(一次性验证码)证明请求确实来自当前登录用户,通过 wp_localize_script() 把服务端生成的 nonce 悄悄塞进页面数据里,前端发请求时带上它。


涉及文件

  • wp-content/themes/fictional-university-theme/src/modules/MyNotes.js (修改)
  • wp-content/themes/fictional-university-theme/functions.php (修改)

代码实现

functions.php:给 wp_localize_script 补上 nonce 属性(在已有的 root_url 旁边追加):

// wp-content/themes/fictional-university-theme/functions.php
wp_localize_script('main-university-js', 'universityData', array(
  'root_url' => get_site_url(),
  'nonce' => wp_create_nonce('wp_rest') // 新增
));

src/modules/MyNotes.jsdeleteNote() 改用 $.ajax() 发送带身份验证的 DELETE 请求(ID 暂时写死,下一讲改成动态):

// wp-content/themes/fictional-university-theme/src/modules/MyNotes.js

deleteNote() {
  $.ajax({
    beforeSend: xhr => {
      xhr.setRequestHeader("X-WP-Nonce", universityData.nonce)
    },
    url: universityData.root_url + "/wp-json/wp/v2/note/58", // 58 是本地测试环境里某条笔记的 ID,实际数字因人而异
    type: "DELETE",
    success: response => {
      console.log("Congrats")
      console.log(response)
    },
    error: response => {
      console.log("Sorry")
      console.log(response)
    }
  })
}

关键改动点:

  • $.getJSON() 只能发 GET 请求,删除/新建/更新这些写操作要改用更底层的 $.ajax(),可以在 type 属性里显式指定 'DELETE' / 'POST'
  • WordPress REST API 的写操作(POST/PUT/DELETE)默认要求身份验证,直接发请求会收到 401 Unauthorized、提示「你没有权限删除这篇文章」——这是刻意的安全设计,不是 bug,如果匿名请求能随便删内容,那才是真正的安全漏洞
  • wp_create_nonce('wp_rest') 在服务端为当前登录用户生成一个绑定到 'wp_rest' 这个 action 名的一次性验证码,通过已有的 wp_localize_script() 一并注入到前端可以访问的 universityData 对象里(这个函数在项目里第一次使用是为了传 root_url,这次只是多加一个属性,机制完全一样)
  • 前端在 $.ajax()beforeSend 回调里,用浏览器原生的 xhr.setRequestHeader() 把这个 nonce 塞进请求头,请求头的名字必须精确匹配 X-WP-Nonce——这是 WordPress REST API 专门检查的固定头名,改成别的名字不会被识别
  • success / error 回调都用 ES6 箭头函数,并在参数里接收 response,方便在控制台打印调试信息,确认请求到底成功还是失败、失败原因是什么

[截图:浏览器开发者工具 Network 面板,DELETE 请求到 wp-json/wp/v2/note/58 的请求头(含 X-WP-Nonce)与响应结果]


Hook / Function 速查

名称类型用途
$.ajax(options)jQuery 方法发送可自定义请求类型(GET/POST/DELETE 等)的请求,比 $.getJSON() 更灵活
wp_create_nonce($action)WP 内建 function为当前用户生成一个绑定到指定 action 名的一次性验证码
xhr.setRequestHeader(name, value)浏览器原生 API在发送请求前手动添加自定义请求头
X-WP-NonceWP REST API 约定的请求头WordPress REST API 专门识别这个请求头来验证请求是否来自已登录用户

常见坑

  • $.getJSON() 尝试发 DELETE 请求——这个方法只能发 GET,写操作必须换用 $.ajax() 并显式指定 type
  • 发请求不带 nonce,直接被 401 拒绝——这是 WordPress 故意的安全机制,不是配置错误,必须补上 X-WP-Nonce 请求头才能通过身份验证
  • beforeSend 后面忘记加逗号——转录里作者自己也提到这个笔误,$.ajax() 参数对象里每个属性之间都要用逗号隔开,少一个逗号整个对象就会解析出错

延伸 / 后续讲座会用到

现在删除请求已经能成功执行,但① ID 还是写死的 58,需要改成动态获取当前点击的是哪条笔记;② 删除成功后页面没有任何视觉反馈,需要手动刷新才能看到笔记消失——这两点都会在下一讲解决。


Sources

Udemy:

  • Become a WordPress Developer: Unlocking Power With Code — Section 19, EP092