WP REST API returns HTML 而不是 JSON

WP REST API returns HTML instead of JSON

https://example.com/wp-json/wp/v2/pages/123 的端点 returns HTML 和 JSON 格式的组合,例如:

<div class="my-class">HTML Content</div>
{ "id" : 123, ... }

functions.php 中有一个摘录过滤器设置输出的 HTML,在这一行:

function my_custom_filter(){
  echo '<div class="my-class">HTML Content</div>';
}
add_filter ('the_excerpt', 'my_custom_filter' );

如何防止此类过滤器干预 JSON 响应?

如果你可以修改过滤器,那么你可以检测过滤器函数内部的 REST API,像这样:

function my_custom_filter(){
    if (! defined("REST_REQUEST")) {
        echo '<div class="my-class">HTML Content</div>';
   }
}
add_filter ('the_excerpt', 'my_custom_filter' );

常量 REST_REQUEST 仅在由 REST API 处理的请求中定义。因此,对于上面的代码,如果请求正在由正常的 WP 请求周期处理,则不会定义常量,因此我们添加的 if 语句将评估为 trueecho 会像往常一样发生。如果定义了常量 ,则 if 的计算结果为 false,过滤器不会向响应添加任何输出。

https://wpseek.com/constant/rest_request/

更新:虽然上面的代码可以工作,但我认为我们可以做得更好。

问题是,如果您有很多过滤器,每个过滤器都需要复制 if 语句,您的代码会变得乱七八糟地检查 REST_REQUEST

  • 是重复的(不是DRY

  • 不是过滤器本身的 concern

  • 不整洁

相反,我们可以通过关注 添加过滤器 .

的代码,在循环的早期引入 REST_REQUEST 检查

这看起来像:

function my_custom_filter(){
    echo '<div class="my-class">HTML Content</div>';
}

if (! defined("REST_REQUEST")) {
    add_filter ('the_excerpt', 'my_custom_filter' );
    //add other HTML filters here
} else {
    //attach REST API actions
} 

这似乎是一个很小的变化(如果你及早抓住它,当过滤器的数量很少时),但它可能会带来一些很大的优势:

  • 它将 REST_REQUEST 检查全部放在一个地方:maintainability

  • 过滤器不需要知道或关心它是否是 REST_REQUEST - 如果它们被调用,它们就可以开始了。保持简单。

  • 你可以在那个地方做其他事情,比如日志记录或基于角色的访问检查:extensibility

在您的应用程序早期进行更改相对容易,但随着您添加更多过滤器和操作,它变得更加困难且容易出错。总是最好第一次就做对!

这里真正的问题是在过滤期间 echoing 内容,假设它被输出到相同的地方 echo。人们应该只修改过滤后的内容。要更正该代码:

function my_custom_filter($excerpt) {
  return '<div class="my-class">HTML Content</div>' . "\n$excerpt";
}
add_filter ('the_excerpt', 'my_custom_filter');

在这种情况下,OP 可能仍然需要条件:

function my_custom_filter($excerpt) {
  return !defined('REST_REQUEST') || !REST_REQUEST ?
    '<div class="my-class">HTML Content</div>' . "\n$excerpt" :
    $excerpt;
}
add_filter ('the_excerpt', 'my_custom_filter');