wordpress

编辑

设置图片

php 复制代码
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: wp
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:152.0) Gecko/20100101 Firefox/152.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en-US;q=0.6,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 77
Origin: http://wp
Connection: keep-alive
Referer: http://wp/wp-admin/post-new.php
Cookie: wordpress_3b7f056b9775e5cd94a7cc21da1e2639=admin%7C1784729158%7Co4s2XNop0AdtgOa1jVMrb2P8MkQ4YZrIUcEyGGlJLdu%7C5f3f858286de7410e0ce3272b0c9e9ffa6c3ea76e9a5bdd36fb9069ded0733eb; wp-saving-post=1-check; wordpress_logged_in_3b7f056b9775e5cd94a7cc21da1e2639=admin%7C1784729158%7Co4s2XNop0AdtgOa1jVMrb2P8MkQ4YZrIUcEyGGlJLdu%7Cfd92c6cc37837f548361f25994268c449baf369a95603b04b1c0d5c9297888af; wp-settings-time-1=1783690363; wp-settings-1=libraryContent%3Dbrowse%26align%3Dleft
Priority: u=0

post_id=17&thumbnail_id=15&_wpnonce=3a6f29f4bf&action=get-post-thumbnail-html
php 复制代码
function wp_ajax_get_post_thumbnail_html() {
//postid
	$post_ID = intval( $_POST['post_id'] );
//post_id=17
	check_ajax_referer( "update-post_$post_ID" );

	if ( ! current_user_can( 'edit_post', $post_ID ) ) {
		wp_die( -1 );
	}

	$thumbnail_id = intval( $_POST['thumbnail_id'] );

	// For backward compatibility, -1 refers to no featured image.
	if ( -1 === $thumbnail_id ) {
		$thumbnail_id = null;
	}

	$return = _wp_post_thumbnail_html( $thumbnail_id, $post_ID );
	wp_send_json_success( $return );
}
php 复制代码
function check_ajax_referer( $action = -1, $query_arg = false, $die = true ) {
//update-post_17

	if ( -1 == $action ) {
		_doing_it_wrong( __FUNCTION__, __( 'You should specify a nonce action to be verified by using the first parameter.' ), '4.7' );
	}

	$nonce = '';
//$_REQUEST[$query_arg] 用于动态获取 HTTP 请求中的参数值,其具体来源取决于请求方式(GET、POST 或 COOKIE)。
	if ( $query_arg && isset( $_REQUEST[ $query_arg ] ) )
		$nonce = $_REQUEST[ $query_arg ];
	elseif ( isset( $_REQUEST['_ajax_nonce'] ) )
		$nonce = $_REQUEST['_ajax_nonce'];
//3a6f29f4bf
	elseif ( isset( $_REQUEST['_wpnonce'] ) )
		$nonce = $_REQUEST['_wpnonce'];
//这里3a6f29f4bf,update-post_17
	$result = wp_verify_nonce( $nonce, $action );

	/**
	 * Fires once the Ajax request has been validated or not.
	 *
	 * @since 2.1.0
	 *
	 * @param string    $action The Ajax nonce action.
	 * @param false|int $result False if the nonce is invalid, 1 if the nonce is valid and generated between
	 *                          0-12 hours ago, 2 if the nonce is valid and generated between 12-24 hours ago.
	 */


//递归
	do_action( 'check_ajax_referer', $action, $result );



	if ( $die && false === $result ) {
		if ( wp_doing_ajax() ) {
			wp_die( -1, 403 );
		} else {
			die( '-1' );
		}
	}

	return $result;
}
php 复制代码
function wp_verify_nonce( $nonce, $action = -1 ) {
//这里3a6f29f4bf,update-post_17



	$nonce = (string) $nonce;
	$user = wp_get_current_user();
	$uid = (int) $user->ID;
	if ( ! $uid ) {
		
		$uid = apply_filters( 'nonce_user_logged_out', $uid, $action );
	}

	if ( empty( $nonce ) ) {
		return false;
	}

	$token = wp_get_session_token();
	$i = wp_nonce_tick();

//这里计算
	$expected = substr( wp_hash( $i . '|' . $action . '|' . $uid . '|' . $token, 'nonce'), -12, 10 );
//对比
	if ( hash_equals( $expected, $nonce ) ) {
		return 1;
	}

//对比
	$expected = substr( wp_hash( ( $i - 1 ) . '|' . $action . '|' . $uid . '|' . $token, 'nonce' ), -12, 10 );
	if ( hash_equals( $expected, $nonce ) ) {
		return 2;
	}

	do_action( 'wp_verify_nonce_failed', $nonce, $action, $user, $token );

//
	return false;
}
endif;
//function_exists 是 PHP 语言的内置函数,用于检测指定函数是否已定义。
if ( !function_exists('wp_create_nonce') ) :
php 复制代码
function apply_filters( $tag, $value ) {
	global $wp_filter, $wp_current_filter;

	$args = array();

	// Do 'all' actions first.
	if ( isset($wp_filter['all']) ) {
		$wp_current_filter[] = $tag;
		$args = func_get_args();
		_wp_call_all_hook($args);
	}

	if ( !isset($wp_filter[$tag]) ) {
		if ( isset($wp_filter['all']) )
			array_pop($wp_current_filter);
		return $value;
	}

	if ( !isset($wp_filter['all']) )
		$wp_current_filter[] = $tag;

	if ( empty($args) )
		$args = func_get_args();

	
	array_shift( $args );
//这里调用
	$filtered = $wp_filter[ $tag ]->apply_filters( $value, $args );

	array_pop( $wp_current_filter );

	return $filtered;
}
php 复制代码
function do_action($tag, $arg = '') {
	global $wp_filter, $wp_actions, $wp_current_filter;

	if ( ! isset($wp_actions[$tag]) )
		$wp_actions[$tag] = 1;
	else
		++$wp_actions[$tag];

	if ( isset($wp_filter['all']) ) {
		$wp_current_filter[] = $tag;
		$all_args = func_get_args();
		_wp_call_all_hook($all_args);
	}

	if ( !isset($wp_filter[$tag]) ) {
		if ( isset($wp_filter['all']) )
			array_pop($wp_current_filter);
		return;
	}

	if ( !isset($wp_filter['all']) )
		$wp_current_filter[] = $tag;

	$args = array();
//
	if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
		$args[] =& $arg[0];
	else
		$args[] = $arg;
	for ( $a = 2, $num = func_num_args(); $a < $num; $a++ )
//处理2
		$args[] = func_get_arg($a);
//这里
	$wp_filter[ $tag ]->do_action( $args );

	array_pop($wp_current_filter);
}
php 复制代码
public function do_action( $args ) {
		$this->doing_action = true;
		$this->apply_filters( '', $args );

		// If there are recursive calls to the current action, we haven't finished it until we get to the last one.
		if ( ! $this->nesting_level ) {
			$this->doing_action = false;
		}
	}
php 复制代码
<?php
/**
 * WordPress Ajax Process Execution
 *
 * @package WordPress
 * @subpackage Administration
 *
 * @link https://codex.wordpress.org/AJAX_in_Plugins
 */


//标识 AJAX 环境‌:将 DOING_AJAX 常量设置为 true,告知 WordPress 内核及插件当前正在处理异步请求,从而跳过常规的页面加载流程(如主题模板渲染),直接执行特定逻辑 。
//定义常量
define( 'DOING_AJAX', true );
//如果没有定义WP_ADMIN
if ( ! defined( 'WP_ADMIN' ) ) {
//定义
	define( 'WP_ADMIN', true );
}

/** Load WordPress Bootstrap */
//固定位置
require_once( dirname( dirname( __FILE__ ) ) . '/wp-load.php' );

//发送来源标头
//允许跨域请求(从前端)。
//校验
send_origin_headers();

//检查参数
if ( empty( $_REQUEST['action'] ) )
	die( '0' );


//包含
require_once( ABSPATH . 'wp-admin/includes/admin.php' );

require_once( ABSPATH . 'wp-admin/includes/ajax-actions.php' );

//请求头
@header( 'Content-Type: text/html; charset=' . get_option( 'blog_charset' ) );
@header( 'X-Robots-Tag: noindex' );
//校验
send_nosniff_header();
//缓存校验
nocache_headers();

//$wp_actions[$tag] 记录这个事件被喊了多少次

//初始化
do_action( 'admin_init' );

//数组
$core_actions_get = array(
	'fetch-list', 'ajax-tag-search', 'wp-compression-test', 'imgedit-preview', 'oembed-cache',
	'autocomplete-user', 'dashboard-widgets', 'logged-in',
);

$core_actions_post = array(
	'oembed-cache', 'image-editor', 'delete-comment', 'delete-tag', 'delete-link',
	'delete-meta', 'delete-post', 'trash-post', 'untrash-post', 'delete-page', 'dim-comment',
	'add-link-category', 'add-tag', 'get-tagcloud', 'get-comments', 'replyto-comment',
	'edit-comment', 'add-menu-item', 'add-meta', 'add-user', 'closed-postboxes',
	'hidden-columns', 'update-welcome-panel', 'menu-get-metabox', 'wp-link-ajax',
	'menu-locations-save', 'menu-quick-search', 'meta-box-order', 'get-permalink',
	'sample-permalink', 'inline-save', 'inline-save-tax', 'find_posts', 'widgets-order',
	'save-widget', 'delete-inactive-widgets', 'set-post-thumbnail', 'date_format', 'time_format',
	'wp-remove-post-lock', 'dismiss-wp-pointer', 'upload-attachment', 'get-attachment',
	'query-attachments', 'save-attachment', 'save-attachment-compat', 'send-link-to-editor',
	'send-attachment-to-editor', 'save-attachment-order', 'heartbeat', 'get-revision-diffs',
	'save-user-color-scheme', 'update-widget', 'query-themes', 'parse-embed', 'set-attachment-thumbnail',
	'parse-media-shortcode', 'destroy-sessions', 'install-plugin', 'update-plugin', 'press-this-save-post',
	'press-this-add-category', 'crop-image', 'generate-password', 'save-wporg-username', 'delete-plugin',
	'search-plugins', 'search-install-plugins', 'activate-plugin', 'update-theme', 'delete-theme',
	'install-theme', 'get-post-thumbnail-html',
);


$core_actions_post[] = 'wp-fullscreen-save-post';

// 获取action,判断是否包含
if ( ! empty( $_GET['action'] ) && in_array( $_GET['action'], $core_actions_get ) )
//拼接
//str_replace 是 PHP 中用于字符串替换的内置函数
//1
//添加插件修改
	add_action( 'wp_ajax_' . $_GET['action'], 'wp_ajax_' . str_replace( '-', '_', $_GET['action'] ), 1 );

//添加插件修改
if ( ! empty( $_POST['action'] ) && in_array( $_POST['action'], $core_actions_post ) )
	add_action( 'wp_ajax_' . $_POST['action'], 'wp_ajax_' . str_replace( '-', '_', $_POST['action'] ), 1 );

//默认
//注册回调函数
add_action( 'wp_ajax_nopriv_heartbeat', 'wp_ajax_nopriv_heartbeat', 1 );

//获取登录用户信息
if ( is_user_logged_in() ) {
	/**
	 * Fires authenticated Ajax actions for logged-in users.
	 *
	 * The dynamic portion of the hook name, `$_REQUEST['action']`,
	 * refers to the name of the Ajax action callback being fired.
	 *
	 * @since 2.1.0
	 */
	do_action( 'wp_ajax_' . $_REQUEST['action'] );
} else {
	/**
	 * Fires non-authenticated Ajax actions for logged-out users.
	 *
	 * The dynamic portion of the hook name, `$_REQUEST['action']`,
	 * refers to the name of the Ajax action callback being fired.
	 *
	 * @since 2.8.0
	 */
	do_action( 'wp_ajax_nopriv_' . $_REQUEST['action'] );
}
// Default status
die( '0' );
php 复制代码
function do_action($tag, $arg = '') {
	global $wp_filter, $wp_actions, $wp_current_filter;

	if ( ! isset($wp_actions[$tag]) )
		$wp_actions[$tag] = 1;
	else
		++$wp_actions[$tag];

	// Do 'all' actions first
	if ( isset($wp_filter['all']) ) {
		$wp_current_filter[] = $tag;
		$all_args = func_get_args();
		_wp_call_all_hook($all_args);
	}

	if ( !isset($wp_filter[$tag]) ) {
		if ( isset($wp_filter['all']) )
			array_pop($wp_current_filter);
		return;
	}

	if ( !isset($wp_filter['all']) )
		$wp_current_filter[] = $tag;

	$args = array();
	if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
		$args[] =& $arg[0];
	else
		$args[] = $arg;
	for ( $a = 2, $num = func_num_args(); $a < $num; $a++ )
		$args[] = func_get_arg($a);

	$wp_filter[ $tag ]->do_action( $args );

	array_pop($wp_current_filter);
}
php 复制代码
function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
//拼接,替换拼接,10,1
	return add_filter($tag, $function_to_add, $priority, $accepted_args);
}
php 复制代码
function add_filter( $tag, $function_to_add, $priority = 10, $accepted_args = 1 ) {
	global $wp_filter;
	if ( ! isset( $wp_filter[ $tag ] ) ) {
		$wp_filter[ $tag ] = new WP_Hook();
	}
//add_filter 是 WordPress 核心函数,用于将自定义函数挂载到特定的‌过滤钩子(Filter Hook)‌上
//插件
	$wp_filter[ $tag ]->add_filter( $tag, $function_to_add, $priority, $accepted_args );
	return true;
}
php 复制代码
function do_action($tag, $arg = '') {
	global $wp_filter, $wp_actions, $wp_current_filter;

	if ( ! isset($wp_actions[$tag]) )
		$wp_actions[$tag] = 1;
	else
		++$wp_actions[$tag];

//特殊"万能监听器"优先('all'),如果存在监听所有事件的钩子 'all',先执行它(入栈记录,避免循环调用)。这相当于"不管喊什么,先让这哥们听见"。
	if ( isset($wp_filter['all']) ) {
		$wp_current_filter[] = $tag;
		$all_args = func_get_args();
		_wp_call_all_hook($all_args);
	}

	if ( !isset($wp_filter[$tag]) ) {
		if ( isset($wp_filter['all']) )
			array_pop($wp_current_filter);
		return;
	}

	if ( !isset($wp_filter['all']) )
		$wp_current_filter[] = $tag;

	$args = array();
	if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
		$args[] =& $arg[0];
	else
		$args[] = $arg;
	for ( $a = 2, $num = func_num_args(); $a < $num; $a++ )
		$args[] = func_get_arg($a);

	$wp_filter[ $tag ]->do_action( $args );

	array_pop($wp_current_filter);
}
php 复制代码
function send_nosniff_header() {
//X-Content-Type-Options: nosniff 是一个HTTP响应头,它的作用是防止浏览器对某些类型的文件进行 MIME 类型嗅探。当服务器返回了一个文件,但是并没有在响应头中明确指出这个文件的 MIME 类型时,浏览器会尝试根据文件的内容猜测其类型。这种行为称为 MIME 类型嗅探。
//不让浏览器制作聪明
	@header( 'X-Content-Type-Options: nosniff' );
}
php 复制代码
function nocache_headers() {
//检查插件
	$headers = wp_get_nocache_headers();
//销毁指定变量或函数,销毁$headers['Last-Modified']
	unset( $headers['Last-Modified'] );

	// 在PHP 5.3及以上版本中,如果你想确保不会发送Last-Modified头部(header),你可以通过几种方式来实现这一点。
//function_exists 是 PHP 语言的内置函数,用于检测指定函数是否已定义。
	if ( function_exists( 'header_remove' ) ) {
//header_remove 是 PHP 内置函数,用于删除此前通过 header() 设置的 HTTP 响应头
		@header_remove( 'Last-Modified' );
	} else {
		// In PHP 5.2, send an empty Last-Modified header, but only as a
		// last resort to override a header already sent. #WP23021

//遍历
		foreach ( headers_list() as $header ) {
//是PHP编程语言的内置函数,用于查找子字符串在目标字符串中首次出现的位置,且不区分大小写
			if ( 0 === stripos( $header, 'Last-Modified' ) ) {
//设置
				$headers['Last-Modified'] = '';
				break;
			}
		}
	}
php 复制代码
function wp_get_nocache_headers() {
	$headers = array(
		'Expires' => 'Wed, 11 Jan 1984 05:00:00 GMT',
		'Cache-Control' => 'no-cache, must-revalidate, max-age=0',
	);
//function_exists 是 PHP 语言的内置函数,用于检测指定函数是否已定义。
//如果有
	if ( function_exists('apply_filters') ) {
//apply_filters 是 ‌WordPress PHP 核心函数‌,用于调用注册在指定钩子上的所有过滤器回调函数,‌修改并返回数据值‌,是实现插件/主题数据扩展的核心机制

//允许插件修改这个地方功能的方法
//允许插件修改nocache_headers值
		$headers = (array) apply_filters( 'nocache_headers', $headers );
	}
//不然这样设置,修改
	$headers['Last-Modified'] = false;
//返回
	return $headers;
}
php 复制代码
function apply_filters( $tag, $value ) {
	global $wp_filter, $wp_current_filter;

	$args = array();
//
	if ( isset($wp_filter['all']) ) {
		$wp_current_filter[] = $tag;
		$args = func_get_args();
		_wp_call_all_hook($args);
	}

	if ( !isset($wp_filter[$tag]) ) {
		if ( isset($wp_filter['all']) )
			array_pop($wp_current_filter);
		return $value;
	}

	if ( !isset($wp_filter['all']) )
		$wp_current_filter[] = $tag;

	if ( empty($args) )
		$args = func_get_args();


	array_shift( $args );

	$filtered = $wp_filter[ $tag ]->apply_filters( $value, $args );

	array_pop( $wp_current_filter );

	return $filtered;
}
php 复制代码
function send_origin_headers() {
//获取‌HTTP 请求头 Origin‌ 的服务器变量,表示发起请求的源(协议 + 域名 + 端口),主要用于‌跨域资源共享(CORS)校验‌。‌‌
	$origin = get_http_origin();
//网络校验,过滤变量
	if ( is_allowed_http_origin( $origin ) ) {
		@header( 'Access-Control-Allow-Origin: ' .  $origin );
		@header( 'Access-Control-Allow-Credentials: true' );
		if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] )
			exit;
		return $origin;
	}
//$_SERVER['REQUEST_METHOD'] 是 PHP 中的一个超全局变量,用于获取当前 HTTP 请求的方法类型。
	if ( 'OPTIONS' === $_SERVER['REQUEST_METHOD'] ) {
//跳转
		status_header( 403 );
		exit;
	}

	return false;
}
php 复制代码
function is_allowed_http_origin( $origin = null ) {
	$origin_arg = $origin;

	if ( null === $origin )
		$origin = get_http_origin();
//过滤白名单
	if ( $origin && ! in_array( $origin, get_allowed_http_origins() ) )
		$origin = '';

	return apply_filters( 'allowed_http_origin', $origin, $origin_arg );
}
php 复制代码
function get_http_origin() {
	$origin = '';
//可以控制?
	if ( ! empty ( $_SERVER[ 'HTTP_ORIGIN' ] ) )
//$_SERVER['HTTP_ORIGIN'] 是 PHP 中用于获取‌HTTP 请求头 Origin‌ 的服务器变量,表示发起请求的源(协议 + 域名 + 端口),主要用于‌跨域资源共享(CORS)校验‌。‌‌

		$origin = $_SERVER[ 'HTTP_ORIGIN' ];

//允许插件修改
	return apply_filters( 'http_origin', $origin );
}
php 复制代码
function do_action($tag, $arg = '') {
	global $wp_filter, $wp_actions, $wp_current_filter;
//如果是空,没注册
	if ( ! isset($wp_actions[$tag]) )
//1
		$wp_actions[$tag] = 1;
	else
//记录
		++$wp_actions[$tag];

	//有all
	if ( isset($wp_filter['all']) ) {
//存储
		$wp_current_filter[] = $tag;
//‌func_get_args()‌ 是 PHP 中用来在函数内部获取所有传入参数的内置函数
		$all_args = func_get_args();
		_wp_call_all_hook($all_args);
	}
//是空,不存在
	if ( !isset($wp_filter[$tag]) ) {
//存在all
		if ( isset($wp_filter['all']) )
//‌array_pop‌ 是 PHP 编程语言中用来‌移除并返回数组最后一个元素‌的函数
			array_pop($wp_current_filter);
		return;
	}
//空

	if ( !isset($wp_filter['all']) )
//存储
		$wp_current_filter[] = $tag;

	$args = array();
	if ( is_array($arg) && 1 == count($arg) && isset($arg[0]) && is_object($arg[0]) ) // array(&$this)
		$args[] =& $arg[0];
	else
		$args[] = $arg;
	for ( $a = 2, $num = func_num_args(); $a < $num; $a++ )
		$args[] = func_get_arg($a);

	$wp_filter[ $tag ]->do_action( $args );

	array_pop($wp_current_filter);
}
php 复制代码
function _wp_call_all_hook($args) {
	global $wp_filter;

	$wp_filter['all']->do_all_hook( $args );
}
php 复制代码
function _wp_call_all_hook($args) {
	global $wp_filter;

	$wp_filter['all']->do_all_hook( $args );
}
php 复制代码
public function do_all_hook( &$args ) {
//记录回调嵌套
		$nesting_level = $this->nesting_level++;
//记录进度
		$this->iterations[ $nesting_level ] = array_keys( $this->callbacks );
//current() 是 PHP 中用来获取数组当前元素值的函数
		do {
			$priority = current( $this->iterations[ $nesting_level ] );
//循环
			foreach ( $this->callbacks[ $priority ] as $the_ ) {
//调用
				call_user_func_array( $the_['function'], $args );
			}
//获取优先级,顺序
		} while ( false !== next( $this->iterations[ $nesting_level ] ) );
//清除
//unset是计算机语言中用于销毁变量或函数的构造器,主要应用于PHP和Shell环境。
		unset( $this->iterations[ $nesting_level ] );
//调用结束退出
		$this->nesting_level--;
	}

编辑图片

php 复制代码
POST /wp-admin/admin-ajax.php HTTP/1.1
Host: wp
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:152.0) Gecko/20100101 Firefox/152.0
Accept: */*
Accept-Language: zh-CN,zh;q=0.9,zh-TW;q=0.8,zh-HK;q=0.7,en-US;q=0.6,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With: XMLHttpRequest
Content-Length: 60
Origin: http://wp
Connection: keep-alive
Referer: http://wp/wp-admin/post-new.php
Cookie: wordpress_3b7f056b9775e5cd94a7cc21da1e2639=admin%7C1784729158%7Co4s2XNop0AdtgOa1jVMrb2P8MkQ4YZrIUcEyGGlJLdu%7C5f3f858286de7410e0ce3272b0c9e9ffa6c3ea76e9a5bdd36fb9069ded0733eb; wordpress_logged_in_3b7f056b9775e5cd94a7cc21da1e2639=admin%7C1784729158%7Co4s2XNop0AdtgOa1jVMrb2P8MkQ4YZrIUcEyGGlJLdu%7Cfd92c6cc37837f548361f25994268c449baf369a95603b04b1c0d5c9297888af; wp-settings-time-1=1783690363; wp-settings-1=libraryContent%3Dbrowse%26align%3Dleft
Priority: u=0

action=image-editor&_ajax_nonce=61116bde13&postid=15&do=open
相关推荐
脉动数据行情3 天前
Java OkHttp 完整封装 GC COMEX 美黄金实时盘口定时拉取工具类
java·okhttp·comex 黄金·外盘贵金属
帅次4 天前
Android 高级工程师面试:网络与数据层 近1年高频追问 18 题
android·网络·okhttp·面试·retrofit·gilde
Java面试题总结5 天前
fastadmin 新手部分功能点
okhttp
殳翰9 天前
向客户端提供JSON数据的方式
okhttp·json
CYY9515 天前
OkHttp 和 Retrofit 封装使用
okhttp·retrofit
CYY9516 天前
OkHttp 的使用
okhttp
朝星1 个月前
Android开发[14]:网络优化之OkHttp
android·okhttp·kotlin
之歆1 个月前
Promise 基础技术深度解析:从回调地狱到链式调用
前端·okhttp·promise
之歆1 个月前
Ajax 基础技术深度解析:XHR 从入门到跨域
前端·ajax·okhttp