什么是HTTPDNS跟随阿里的httpdns demo一步一步了解httpdns

article/2025/10/25 12:56:13

阿里巴巴是这样说的

HTTPDNS使用HTTP协议进行域名解析,代替现有基于UDP的DNS协议,域名解析请求直接发送到阿里云的HTTPDNS服务器,从而绕过运营商的Local DNS,能够避免Local DNS造成的域名劫持问题和调度不精准问题。

分析demo

https://github.com/aliyun/alicloud-android-demo.git

image.png

普通场景 就是普通的http请求
sni场景 就是 server name Indication 场景
选择里面的httpdns_android_demo打开MainActivity。

private static final String APPLE_URL = "www.apple.com";private static final String TAOBAO_URL = "m.taobao.com";private static final String DOUBAN_URL = "dou.bz";private static final String ALIYUN_URL = "aliyun.com";private static final String HTTP_SCHEMA = "http://";private static final String HTTPS_SCHEMA = "https://";private static final String TAG = "httpdns_android_demo";

先看看普通请求,

/*** 通过IP直连方式发起普通请求示例* 1. 通过IP直连时,为绕开服务域名检查,需要在Http报头中设置Host字段*/private void normalReqeust() {pool.execute(new Runnable() {@Overridepublic void run() {try {// 发送网络请求String originalUrl = HTTP_SCHEMA + TAOBAO_URL;URL url = new URL(originalUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 异步接口获取IPString ip = httpdns.getIpByHostAsync(url.getHost());if (ip != null) {// 通过HTTPDNS获取IP成功,进行URL替换和HOST头设置Log.d(TAG, "Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");sendConsoleMessage("Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");String newUrl = originalUrl.replaceFirst(url.getHost(), ip);conn = (HttpURLConnection) new URL(newUrl).openConnection();// 设置HTTP请求头Host域conn.setRequestProperty("Host", url.getHost());}DataInputStream dis = new DataInputStream(conn.getInputStream());int len;byte[] buff = new byte[4096];StringBuilder response = new StringBuilder();while ((len = dis.read(buff)) != -1) {response.append(new String(buff, 0, len));}Log.d(TAG, "Response: " + response.toString());sendConsoleMessage("Get response from " + url.getHost() + ". Please check response detail from log.");} catch (Throwable throwable) {Log.e(TAG, "normal request failed.", throwable);sendConsoleMessage("Normal request failed." + " Please check error detail from log.");}}});}

从这例子不难看出,阿里的demo首先是创建一个url连接,获取host
host就是不包含http 的域名(比如s.taobao.com)然后调用通过sdk中的String ip = httpdns.getIpByHostAsync(url.getHost()); 也就是通过阿里自己的http请求查询这个host对应的ip地址,如果查询成功,那么HttpURLConnection会被重新创建,而且是通过ip进行创建,另外为了不丢失域名,所以这里做了一个操作就是设置请求头"Host"
也就是调用conn.setRequestProperty("Host", url.getHost());

整个过程就是通过 域名查询ip,然后通过ip进行请求的操作,
但是这个业务逻辑本身是dns自身做的事情,现在已经绕过了,直接交给阿里的http dns服务器进行操作。

不过不管怎么操作,这httpdns自身还是得通过运营商的dns进行请求,当然他们自己的也可以做缓存,或者ip地址可靠也可以直接访问比如http://203.107.1.33/100000/d?host=www.aliyun.com
他们是这样说的

考虑到服务IP防攻击之类的安全风险,为保障服务可用性,HTTPDNS同时提供多个服务IP,当某个服务IP在异常情况下不可用时,可以使用其它服务IP进行重试。上述文档中使用的203.107.1.33是其中一个服务IP。

HTTPDNS提供Android SDK和iOS SDK,两个平台的SDK中已经做了多IP轮转和出错重试的策略,通常情况下,建议开发者直接集成SDK即可,不需要自己手动调用HTTP API接口。

如果使用场景特殊,无法使用SDK,需要直接访问HTTP API接口,请提工单联系我们,我们将根据您的具体使用场景,为您提供多个服务IP和相关的安全建议。

具体参考https://help.aliyun.com/document_detail/52679.html?spm=a2c4g.11186623.2.21.11321d22lF9Vbp#1.1 访问方式

再看看https

/*** 通过IP直连方式发起https请求示例* 1. 通过IP直连时,为绕开服务域名检查,需要在Http报头中设置Host字段* 2. 为通过证书检查,需要自定义证书验证逻辑*/private void httpsRequest() {pool.execute(new Runnable() {@Overridepublic void run() {try {String originalUrl = HTTPS_SCHEMA + TAOBAO_URL + "/?sprefer=sypc00";URL url = new URL(originalUrl);HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();// 同步接口获取IPString ip = httpdns.getIpByHostAsync(url.getHost());if (ip != null) {// 通过HTTPDNS获取IP成功,进行URL替换和HOST头设置Log.d(TAG, "Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");sendConsoleMessage("Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");String newUrl = originalUrl.replaceFirst(url.getHost(), ip);conn = (HttpsURLConnection) new URL(newUrl).openConnection();// 设置HTTP请求头Host域conn.setRequestProperty("Host", url.getHost());}final HttpsURLConnection finalConn = conn;conn.setHostnameVerifier(new HostnameVerifier() {/** 关于这个接口的说明,官方有文档描述:* This is an extended verification option that implementers can provide.* It is to be used during a handshake if the URL's hostname does not match the* peer's identification hostname.** 使用HTTPDNS后URL里设置的hostname不是远程的主机名(如:m.taobao.com),与证书颁发的域不匹配,* Android HttpsURLConnection提供了回调接口让用户来处理这种定制化场景。* 在确认HTTPDNS返回的源站IP与Session携带的IP信息一致后,您可以在回调方法中将待验证域名替换为原来的真实域名进行验证。**/@Overridepublic boolean verify(String hostname, SSLSession session) {String host = finalConn.getRequestProperty("Host");if (null == host) {host = finalConn.getURL().getHost();}return HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session);}});DataInputStream dis = new DataInputStream(conn.getInputStream());int len;byte[] buff = new byte[4096];StringBuilder response = new StringBuilder();while ((len = dis.read(buff)) != -1) {response.append(new String(buff, 0, len));}Log.d(TAG, "Response: " + response.toString());sendConsoleMessage("Get reponse from " + url.getHost() + ". Please check response detail from log.");} catch (Exception e) {e.printStackTrace();sendConsoleMessage("Get reponse failed. Please check error detail from log.");}}});}

处理重定向

private void recursiveRequest(String path, String reffer) {URL url;HttpsURLConnection conn = null;try {url = new URL(path);conn = (HttpsURLConnection) url.openConnection();// 同步接口获取IPString ip = httpdns.getIpByHostAsync(url.getHost());if (ip != null) {// 通过HTTPDNS获取IP成功,进行URL替换和HOST头设置Log.d(TAG, "Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");sendConsoleMessage("Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");String newUrl = path.replaceFirst(url.getHost(), ip);conn = (HttpsURLConnection) new URL(newUrl).openConnection();// 设置HTTP请求头Host域conn.setRequestProperty("Host", url.getHost());}conn.setConnectTimeout(30000);conn.setReadTimeout(30000);conn.setInstanceFollowRedirects(false);HttpDnsTLSSniSocketFactory sslSocketFactory = new HttpDnsTLSSniSocketFactory(conn);conn.setSSLSocketFactory(sslSocketFactory);final HttpsURLConnection finalConn = conn;conn.setHostnameVerifier(new HostnameVerifier() {/** 关于这个接口的说明,官方有文档描述:* This is an extended verification option that implementers can provide.* It is to be used during a handshake if the URL's hostname does not match the* peer's identification hostname.** 使用HTTPDNS后URL里设置的hostname不是远程的主机名(如:m.taobao.com),与证书颁发的域不匹配,* Android HttpsURLConnection提供了回调接口让用户来处理这种定制化场景。* 在确认HTTPDNS返回的源站IP与Session携带的IP信息一致后,您可以在回调方法中将待验证域名替换为原来的真实域名进行验证。**/@Overridepublic boolean verify(String hostname, SSLSession session) {String host = finalConn.getRequestProperty("Host");if (null == host) {host = finalConn.getURL().getHost();}return HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session);}});int code = conn.getResponseCode();// Network blockif (needRedirect(code)) {//临时重定向和永久重定向location的大小写有区分String location = conn.getHeaderField("Location");if (location == null) {location = conn.getHeaderField("location");}if (!(location.startsWith(HTTP_SCHEMA) || location.startsWith(HTTPS_SCHEMA))) {//某些时候会省略host,只返回后面的path,所以需要补全urlURL originalUrl = new URL(path);location = originalUrl.getProtocol() + "://"+ originalUrl.getHost() + location;}recursiveRequest(location, path);} else {// redirect finish.DataInputStream dis = new DataInputStream(conn.getInputStream());int len;byte[] buff = new byte[4096];StringBuilder response = new StringBuilder();while ((len = dis.read(buff)) != -1) {response.append(new String(buff, 0, len));}Log.d(TAG, "Response: " + response.toString());sendConsoleMessage("Get reponse from " + url.getHost() + ". Please check response detail from log.");}} catch (MalformedURLException e) {Log.w(TAG, "recursiveRequest MalformedURLException", e);} catch (IOException e) {Log.w(TAG, "recursiveRequest IOException");} catch (Exception e) {Log.w(TAG, "unknow exception");} finally {if (conn != null) {conn.disconnect();}}}private boolean needRedirect(int code) {return code >= 300 && code < 400;}

预解析域名
顾名思义,在请求某个东西之前先请求,比如app刚打开的时候。
这样通过sdk进行查询就会直接从缓存中取出。

/*** 设置预解析域名列表代码示例*/private void setPreResoveHosts() {// 设置预解析域名列表// 可以替换成您在后台配置的域名httpdns.setPreResolveHosts(new ArrayList<>(Arrays.asList(APPLE_URL, ALIYUN_URL, TAOBAO_URL,  DOUBAN_URL)));sendConsoleMessage("设置预解析域名成功");}

降级解析

/*** 自定义降级逻辑代码示例*/private void setDegrationFilter() {DegradationFilter filter = new DegradationFilter() {@Overridepublic boolean shouldDegradeHttpDNS(String hostName) {// 此处可以自定义降级逻辑,例如www.taobao.com不使用HttpDNS解析// 参照HttpDNS API文档,当存在中间HTTP代理时,应选择降级,使用Local DNSreturn hostName.equals(DOUBAN_URL);}};// 将filter传进httpdns,解析时会回调shouldDegradeHttpDNS方法,判断是否降级httpdns.setDegradationFilter(filter);sendConsoleMessage("自定义降级逻辑成功");}

降级解析就是不用他们的dns,使用运营商的。

处理webview

class WebviewTlsSniSocketFactory extends SSLSocketFactory {private final String TAG = WebviewTlsSniSocketFactory.class.getSimpleName();HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();private HttpsURLConnection conn;public WebviewTlsSniSocketFactory(HttpsURLConnection conn) {this.conn = conn;}@Overridepublic Socket createSocket() throws IOException {return null;}@Overridepublic Socket createSocket(String host, int port) throws IOException, UnknownHostException {return null;}@Overridepublic Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException, UnknownHostException {return null;}@Overridepublic Socket createSocket(InetAddress host, int port) throws IOException {return null;}@Overridepublic Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {return null;}// TLS layer@Overridepublic String[] getDefaultCipherSuites() {return new String[0];}@Overridepublic String[] getSupportedCipherSuites() {return new String[0];}@Overridepublic Socket createSocket(Socket plainSocket, String host, int port, boolean autoClose) throws IOException {String peerHost = this.conn.getRequestProperty("Host");if (peerHost == null)peerHost = host;Log.i(TAG, "customized createSocket. host: " + peerHost);InetAddress address = plainSocket.getInetAddress();if (autoClose) {// we don't need the plainSocketplainSocket.close();}// create and connect SSL socket, but don't do hostname/certificate verification yetSSLCertificateSocketFactory sslSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0);SSLSocket ssl = (SSLSocket) sslSocketFactory.createSocket(address, port);// enable TLSv1.1/1.2 if availablessl.setEnabledProtocols(ssl.getSupportedProtocols());// set up SNI before the handshakeif (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {Log.i(TAG, "Setting SNI hostname");sslSocketFactory.setHostname(ssl, peerHost);} else {Log.d(TAG, "No documented SNI support on Android <4.2, trying with reflection");try {java.lang.reflect.Method setHostnameMethod = ssl.getClass().getMethod("setHostname", String.class);setHostnameMethod.invoke(ssl, peerHost);} catch (Exception e) {Log.w(TAG, "SNI not useable", e);}}// verify hostname and certificateSSLSession session = ssl.getSession();if (!hostnameVerifier.verify(peerHost, session))throw new SSLPeerUnverifiedException("Cannot verify hostname: " + peerHost);Log.i(TAG, "Established " + session.getProtocol() + " connection with " + session.getPeerHost() +" using " + session.getCipherSuite());return ssl;}}webView.setWebViewClient(new WebViewClient() {@SuppressLint("NewApi")@Overridepublic WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {String scheme = request.getUrl().getScheme().trim();String method = request.getMethod();Map<String, String> headerFields = request.getRequestHeaders();String url = request.getUrl().toString();Log.e(TAG, "url:" + url);// 无法拦截body,拦截方案只能正常处理不带body的请求;if ((scheme.equalsIgnoreCase("http") || scheme.equalsIgnoreCase("https"))&& method.equalsIgnoreCase("get")) {try {URLConnection connection = recursiveRequest(url, headerFields, null);if (connection == null) {Log.e(TAG, "connection null");return super.shouldInterceptRequest(view, request);}// 注*:对于POST请求的Body数据,WebResourceRequest接口中并没有提供,这里无法处理String contentType = connection.getContentType();String mime = getMime(contentType);String charset = getCharset(contentType);HttpURLConnection httpURLConnection = (HttpURLConnection)connection;int statusCode = httpURLConnection.getResponseCode();String response = httpURLConnection.getResponseMessage();Map<String, List<String>> headers = httpURLConnection.getHeaderFields();Set<String> headerKeySet = headers.keySet();Log.e(TAG, "code:" + httpURLConnection.getResponseCode());Log.e(TAG, "mime:" + mime + "; charset:" + charset);// 无mime类型的请求不拦截if (TextUtils.isEmpty(mime)) {Log.e(TAG, "no MIME");return super.shouldInterceptRequest(view, request);} else {// 二进制资源无需编码信息if (!TextUtils.isEmpty(charset) || (isBinaryRes(mime))) {WebResourceResponse resourceResponse = new WebResourceResponse(mime, charset, httpURLConnection.getInputStream());resourceResponse.setStatusCodeAndReasonPhrase(statusCode, response);Map<String, String> responseHeader = new HashMap<String, String>();for (String key: headerKeySet) {// HttpUrlConnection可能包含key为null的报头,指向该http请求状态码responseHeader.put(key, httpURLConnection.getHeaderField(key));}resourceResponse.setResponseHeaders(responseHeader);return resourceResponse;} else {Log.e(TAG, "non binary resource for " + mime);return super.shouldInterceptRequest(view, request);}}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}return super.shouldInterceptRequest(view, request);}@Overridepublic WebResourceResponse shouldInterceptRequest(WebView view, String url) {// API < 21 只能拦截URL参数return super.shouldInterceptRequest(view, url);}});webView.loadUrl(targetUrl);}public URLConnection recursiveRequest(String path, Map<String, String> headers, String reffer) {HttpURLConnection conn;URL url = null;try {url = new URL(path);conn = (HttpURLConnection) url.openConnection();// 异步接口获取IPString ip = httpdns.getIpByHostAsync(url.getHost());if (ip != null) {// 通过HTTPDNS获取IP成功,进行URL替换和HOST头设置Log.d(TAG, "Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");String newUrl = path.replaceFirst(url.getHost(), ip);conn = (HttpURLConnection) new URL(newUrl).openConnection();if (headers != null) {for (Map.Entry<String, String> field : headers.entrySet()) {conn.setRequestProperty(field.getKey(), field.getValue());}}// 设置HTTP请求头Host域conn.setRequestProperty("Host", url.getHost());} else {return null;}conn.setConnectTimeout(30000);conn.setReadTimeout(30000);conn.setInstanceFollowRedirects(false);if (conn instanceof HttpsURLConnection) {final HttpsURLConnection httpsURLConnection = (HttpsURLConnection)conn;WebviewTlsSniSocketFactory sslSocketFactory = new WebviewTlsSniSocketFactory((HttpsURLConnection) conn);// sni场景,创建SSLScockethttpsURLConnection.setSSLSocketFactory(sslSocketFactory);// https场景,证书校验httpsURLConnection.setHostnameVerifier(new HostnameVerifier() {@Overridepublic boolean verify(String hostname, SSLSession session) {String host = httpsURLConnection.getRequestProperty("Host");if (null == host) {host = httpsURLConnection.getURL().getHost();}return HttpsURLConnection.getDefaultHostnameVerifier().verify(host, session);}});}int code = conn.getResponseCode();// Network blockif (needRedirect(code)) {// 原有报头中含有cookie,放弃拦截if (containCookie(headers)) {return null;}String location = conn.getHeaderField("Location");if (location == null) {location = conn.getHeaderField("location");}if (location != null) {if (!(location.startsWith("http://") || location.startsWith("https://"))) {//某些时候会省略host,只返回后面的path,所以需要补全urlURL originalUrl = new URL(path);location = originalUrl.getProtocol() + "://"+ originalUrl.getHost() + location;}Log.e(TAG, "code:" + code + "; location:" + location + "; path" + path);return recursiveRequest(location, headers, path);} else {// 无法获取location信息,让浏览器获取return null;}} else {// redirect finish.Log.e(TAG, "redirect finish");return conn;}} catch (MalformedURLException e) {Log.w(TAG, "recursiveRequest MalformedURLException");} catch (IOException e) {Log.w(TAG, "recursiveRequest IOException");} catch (Exception e) {Log.w(TAG, "unknow exception");}return null;}

其他demo

public class NetworkRequestUsingHttpDNS {private static HttpDnsService httpdns;// 填入您的HTTPDNS accoutID信息,您可以从HTTPDNS控制台获取该信息private static String accountID = "100000";// 您的热点域名private static final String[] TEST_URL = {"http://www.aliyun.com", "http://www.taobao.com"};public static void main(final Context ctx) {try {// 设置APP Context和Account ID,并初始化HTTPDNShttpdns = HttpDns.getService(ctx, accountID);// DegradationFilter用于自定义降级逻辑// 通过实现shouldDegradeHttpDNS方法,可以根据需要,选择是否降级DegradationFilter filter = new DegradationFilter() {@Overridepublic boolean shouldDegradeHttpDNS(String hostName) {// 此处可以自定义降级逻辑,例如www.taobao.com不使用HttpDNS解析// 参照HttpDNS API文档,当存在中间HTTP代理时,应选择降级,使用Local DNSreturn hostName.equals("www.taobao.com") || detectIfProxyExist(ctx);}};// 将filter传进httpdns,解析时会回调shouldDegradeHttpDNS方法,判断是否降级httpdns.setDegradationFilter(filter);// 设置预解析域名列表,真正使用时,建议您将预解析操作放在APP启动函数中执行。预解析操作为异步行为,不会阻塞您的启动流程httpdns.setPreResolveHosts(new ArrayList<>(Arrays.asList("www.aliyun.com", "www.taobao.com")));// 允许返回过期的IP,通过设置允许返回过期的IP,配合异步查询接口,我们可以实现DNS懒更新策略httpdns.setExpiredIPEnabled(true);// 发送网络请求String originalUrl = "http://www.aliyun.com";URL url = new URL(originalUrl);HttpURLConnection conn = (HttpURLConnection) url.openConnection();// 异步接口获取IP,当IP TTL过期时,由于采用DNS懒更新策略,我们可以直接从内存获得最近的DNS解析结果,同时HTTPDNS SDK在后台自动更新对应域名的解析结果ip = httpdns.getIpByHostAsync(url.getHost());if (ip != null) {// 通过HTTPDNS获取IP成功,进行URL替换和HOST头设置Log.d("HTTPDNS Demo", "Get IP: " + ip + " for host: " + url.getHost() + " from HTTPDNS successfully!");String newUrl = originalUrl.replaceFirst(url.getHost(), ip);conn = (HttpURLConnection) new URL(newUrl).openConnection();}DataInputStream dis = new DataInputStream(conn.getInputStream());int len;byte[] buff = new byte[4096];StringBuilder response = new StringBuilder();while ((len = dis.read(buff)) != -1) {response.append(new String(buff, 0, len));}Log.e("HTTPDNS Demo", "Response: " + response.toString());} catch (Exception e) {e.printStackTrace();}}/*** 检测系统是否已经设置代理,请参考HttpDNS API文档。*/public static boolean detectIfProxyExist(Context ctx) {boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH;String proxyHost;int proxyPort;if (IS_ICS_OR_LATER) {proxyHost = System.getProperty("http.proxyHost");String port = System.getProperty("http.proxyPort");proxyPort = Integer.parseInt(port != null ? port : "-1");} else {proxyHost = android.net.Proxy.getHost(ctx);proxyPort = android.net.Proxy.getPort(ctx);}return proxyHost != null && proxyPort != -1;}
}

参考https://help.aliyun.com/document_detail/30143.html
okhttp接入httpdns最佳实践https://help.aliyun.com/document_detail/52008.html


http://chatgpt.dhexx.cn/article/k6WVgHwa.shtml

相关文章

HTTPDNS 快速入门

作者&#xff1a;林子 对于互联网&#xff0c;域名解析是访问的第一步&#xff0c;而这一步很多时候会导致访问速度慢、失败&#xff0c;甚至无法访问等&#xff0c;那么怎么解决这些问题呢&#xff1f;本文将带你快速入门 HTTPDNS&#xff0c;怎么解决 LocalDNS 异常导致用户访…

HttpDNS 服务详解

http://www.ttlsa.com/web/httpdns-detailed-service/ 摘要 对于互联网&#xff0c;域名是访问的第一跳&#xff0c;而这一跳很多时候会“失足”&#xff0c;导致访问错误内容&#xff0c;失败连接等&#xff0c;让我们在互联网上畅游的爽快瞬间消失&#xff0c;而对于这关键…

HTTPDNS 解析

简介 HTTPDNS使用HTTP协议进行域名解析&#xff0c;代替现有基于UDP的DNS协议&#xff0c;域名解析请求直接发送到阿里云的HTTPDNS服务器&#xff0c;从而绕过运营商的Local DNS&#xff0c;能够避免Local DNS造成的域名劫持问题和调度不精准问题。 HTTPDNS是面向移动开发者推…

HttpDNS简述

顾名思义&#xff0c;httpdns就是基于http协议进行域名解析的基础服务。可以用来代替传统的基于tcp/udp协议的dns服务。 HttpDNS解决的问题 HttpDNS 目的在于解决移动互联网中传统DNS 解析超时&#xff08;异常&#xff09;、域名劫持等问题&#xff1a; 传统DNS的现状&#x…

关于HTTPDNS,你知道多少?

导读&#xff1a; 全网域名劫持率高&#xff0c;域名解析失败、解析超时&#xff0c;IP调度不精准&#xff0c;域名解析变更生效不实时&#xff0c;这些问题是否一直困扰着你&#xff1f;作为网络请求最前置的环节&#xff0c;域名解析的稳定与精准程度直接决定了APP的访问体验…

Windows 桌面美化

大家都是程序员&#xff0c;我平时上班用mac&#xff0c;mac没啥想调整的&#xff0c;自己用的win想搞美化一点&#xff0c;就网上搜了不少东西。 这是我现在的桌面&#xff0c;桌面软件用的是wallpaper&#xff0c;stream18元有售。内部还有福利。。。。 我只保留了垃圾桶&…

WIN10桌面美化(折腾)

WIN10桌面美化(折腾) 先上我现在桌面的截图:我觉得mac dock挺好看的,所以我把任务栏改成Macdock 修改 :任务栏 修改工具 :MyDock (点击下载) 修改方法 : 先把win任务栏隐藏起来 下载解压

WIN10美化桌面

说到美化桌面这方面&#xff0c;每一个人都有自己的想法。没有最好&#xff0c;只有最适合。由于自己有强迫症这一点&#xff0c;所以我的方案是适合强迫症的。废话不多说&#xff0c;先上桌面截图吧&#xff1a; 下面说下步骤&#xff1a; 由于有强迫症&#xff0c;所以桌面一…

win10电脑桌面html,手把手教你美化win10电脑桌面的小技巧

电脑开机之后首先映入眼帘的是桌面&#xff0c;如果桌面背景不美观&#xff0c;会影响一整天的工作心情。美化Win10系统桌面大家只停留上更换桌面壁纸&#xff0c;改改图标又或者是字体&#xff0c;没什么个性。追求个性化的用户想要打造不一般的桌面&#xff0c;比如主题&…

win10主题美化(单)

网站&#xff1a;https://zhutix.com/tag/win10-zhuti/ Win10美化教程 以下内容新手必看必做&#xff0c;否则请做好重装系统的准备&#xff0c;一切后果自负 01、增加系统登录密码️ 并 关闭系统自动更新&#xff0c;可预防95%因美化引起的闪屏&#xff0c;万一闪屏可以在登录…

171029 windows10 桌面美化

最终效果 视频 https://www.youtube.com/watch?v6-5mromnf3c 壁纸 http://qph.ec.quoracdn.net/main-qimg-2cde0a53288265fd5dbe4285d60c3afc RocketDock https://rocketdock.com/download Win10-Theme https://limera1n.deviantart.com/art/Win10-Theme-for-RocketD…

WIn10桌面美化(一)Rainmeter的使用

随着时代的进步&#xff0c;人们使用电脑的频率越来越高&#xff0c;死板的桌面已经无法满足我们的需求&#xff0c;下面我就简单介绍美化桌面的方法。 这里我使用的是一款名为 Rainmeter 的软件 &#xff0c;Rainmeter原本是一个系统状态监视软件&#xff0c;由于其强大的可定…

美化你的Xfce桌面

Xfce的鼎鼎大名你是不是早有耳闻了&#xff1f;Xfce是一个很好的轻量级桌面环境&#xff0c;占用系统资源少是他的优点&#xff0c;你可能会在一些嵌入式系统中见到他的身影&#xff0c;但他也有一个缺点&#xff0c;那就是默认的界面看起来有点旧。但这是不Xfce的错&#xff0…

Win10桌面美化(桌面数字时钟,悬浮侧边栏、透明任务栏、底部居中软件图标)

生命在于折腾&#xff0c;一个简洁清爽的界面可以让人心情愉悦&#xff0c;整理分享一下我的Win10桌面美化历程&#xff0c;先上效果图&#xff1a; 首先得准备一张好看的壁纸&#xff0c;文中涉及到的图片&#xff0c;软件已经全部打包&#xff0c;下载链接在文末。 1. 桌面数…

Win10值得推荐的软件,提升效率和桌面美观

某乎真强&#xff0c;删后留存 桌面镇楼&#xff0c;最近重装了win10&#xff0c;感觉系统又变得流畅了许多&#xff1f; 因为没有备份&#xff0c;所以软件都重新装了一遍&#xff0c;下面来记录一下Win10下不错的软件吧。 mac的可以查看另一篇文章&#xff1a;MAC值得推荐…

六款顶级桌面美化软件推荐(Windows)

电脑已经渐渐融入我们日常的生活&#xff0c;每天打开电脑娱乐和工作成了多数人生活的一部分。当然&#xff0c;看什么东西时间一长都会产生疲乏和厌倦感&#xff0c;所以不少软件开发者瞄准了系统美化这一块&#xff0c;制作出了很多独具特色的系统美化工具&#xff0c;并且解…

技巧:win10的另一种美化字体的方式,使用noMeiryoUI

目录 1. 前提2. 字体选择3. 查看已经安装的字体并查看效果4. 安装软件修改系统字体5. 修改浏览器字体 1. 前提 21年的时候写了一篇文章&#xff0c;《Windows10下美化字体&#xff0c;达到类似mac的效果》&#xff0c;当时还很迷恋macType这个软件的使用&#xff0c;觉得好牛逼…

Win10美化

我喜欢比较纯净的桌面&#xff0c;也就是桌面上不放任何图标、文件和文件夹&#xff0c;又嫌搜索应用太麻烦&#xff0c;所以启动应用就落在了win10自带的开始屏幕上&#xff0c;但是自带的磁贴着实简陋&#xff0c;因此就踏上了磁贴美化的漫漫长路。 1.默认效果功能分区整齐排…

windows 10 主题美化

摘要&#xff1a;windows10系统采用扁平化设计&#xff0c;但是我们总有审美疲劳&#xff0c;所以我们也想像以前的windows7系统一样可以更改主题&#xff0c;但是windows 10系统安全性比windows 7系统更加高&#xff0c;也导致了windows10的系统更换主题的麻烦&#xff0c;因为…

Windows桌面美化

Windows桌面美化 链接: https://pan.baidu.com/s/1CZ2EzTbfQBRETdVPHufkrw 提取码: pw9p