函数文档

wp_ajax_heartbeat()

💡 云策文档标注

概述

wp_ajax_heartbeat() 是 WordPress 中处理 Heartbeat API 的 AJAX 回调函数,用于在用户登录状态下管理服务器与客户端之间的实时通信。它验证 nonce、处理传入数据,并通过过滤器允许开发者自定义响应。

关键要点

  • 函数仅在用户登录时运行,通过 AJAX 处理 Heartbeat API 请求。
  • 验证 $_POST['_nonce'] 以确保安全性,使用 wp_verify_nonce() 检查 nonce 状态。
  • 处理 $_POST['data'] 数据,使用 wp_unslash() 移除斜杠,并支持通过 screen_id 识别当前屏幕。
  • 提供多个过滤器(如 heartbeat_received、heartbeat_send、wp_refresh_nonces)和动作(heartbeat_tick)供开发者扩展功能。
  • 返回 JSON 响应,包含服务器时间(server_time)和可能的错误状态(如 nonces_expired)。

代码示例

function wp_ajax_heartbeat() {
    if ( empty( $_POST['_nonce'] ) ) {
        wp_send_json_error();
    }

    $response    = array();
    $data        = array();
    $nonce_state = wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' );

    if ( ! empty( $_POST['screen_id'] ) ) {
        $screen_id = sanitize_key( $_POST['screen_id'] );
    } else {
        $screen_id = 'front';
    }

    if ( ! empty( $_POST['data'] ) ) {
        $data = wp_unslash( (array) $_POST['data'] );
    }

    if ( 1 !== $nonce_state ) {
        $response = apply_filters( 'wp_refresh_nonces', $response, $data, $screen_id );

        if ( false === $nonce_state ) {
            $response['nonces_expired'] = true;
            wp_send_json( $response );
        }
    }

    if ( ! empty( $data ) ) {
        $response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
    }

    $response = apply_filters( 'heartbeat_send', $response, $screen_id );

    do_action( 'heartbeat_tick', $response, $screen_id );

    $response['server_time'] = time();

    wp_send_json( $response );
}

注意事项

  • 确保在 AJAX 请求中正确传递 _nonce 参数,否则函数会返回 JSON 错误。
  • nonce 验证失败时,会触发 wp_refresh_nonces 过滤器,并可能设置 nonces_expired 标志。
  • 开发者可以利用提供的过滤器和动作来定制 Heartbeat 行为,例如添加自定义数据或替换传输机制。
  • 函数返回的 JSON 响应包含 server_time,可用于同步客户端与服务器时间。

📄 原文内容

Handles the Heartbeat API via AJAX.

Description

Runs when the user is logged in.

Source

function wp_ajax_heartbeat() {
	if ( empty( $_POST['_nonce'] ) ) {
		wp_send_json_error();
	}

	$response    = array();
	$data        = array();
	$nonce_state = wp_verify_nonce( $_POST['_nonce'], 'heartbeat-nonce' );

	// 'screen_id' is the same as $current_screen->id and the JS global 'pagenow'.
	if ( ! empty( $_POST['screen_id'] ) ) {
		$screen_id = sanitize_key( $_POST['screen_id'] );
	} else {
		$screen_id = 'front';
	}

	if ( ! empty( $_POST['data'] ) ) {
		$data = wp_unslash( (array) $_POST['data'] );
	}

	if ( 1 !== $nonce_state ) {
		/**
		 * Filters the nonces to send to the New/Edit Post screen.
		 *
		 * @since 4.3.0
		 *
		 * @param array  $response  The Heartbeat response.
		 * @param array  $data      The $_POST data sent.
		 * @param string $screen_id The screen ID.
		 */
		$response = apply_filters( 'wp_refresh_nonces', $response, $data, $screen_id );

		if ( false === $nonce_state ) {
			// User is logged in but nonces have expired.
			$response['nonces_expired'] = true;
			wp_send_json( $response );
		}
	}

	if ( ! empty( $data ) ) {
		/**
		 * Filters the Heartbeat response received.
		 *
		 * @since 3.6.0
		 *
		 * @param array  $response  The Heartbeat response.
		 * @param array  $data      The $_POST data sent.
		 * @param string $screen_id The screen ID.
		 */
		$response = apply_filters( 'heartbeat_received', $response, $data, $screen_id );
	}

	/**
	 * Filters the Heartbeat response sent.
	 *
	 * @since 3.6.0
	 *
	 * @param array  $response  The Heartbeat response.
	 * @param string $screen_id The screen ID.
	 */
	$response = apply_filters( 'heartbeat_send', $response, $screen_id );

	/**
	 * Fires when Heartbeat ticks in logged-in environments.
	 *
	 * Allows the transport to be easily replaced with long-polling.
	 *
	 * @since 3.6.0
	 *
	 * @param array  $response  The Heartbeat response.
	 * @param string $screen_id The screen ID.
	 */
	do_action( 'heartbeat_tick', $response, $screen_id );

	// Send the current time according to the server.
	$response['server_time'] = time();

	wp_send_json( $response );
}

Hooks

apply_filters( ‘heartbeat_received’, array $response, array $data, string $screen_id )

Filters the Heartbeat response received.

apply_filters( ‘heartbeat_send’, array $response, string $screen_id )

Filters the Heartbeat response sent.

do_action( ‘heartbeat_tick’, array $response, string $screen_id )

Fires when Heartbeat ticks in logged-in environments.

apply_filters( ‘wp_refresh_nonces’, array $response, array $data, string $screen_id )

Filters the nonces to send to the New/Edit Post screen.

Changelog

Version Description
3.6.0 Introduced.