SpringBoot2.0整合Disconf配置中心实战

Disconf简介

配置中心使用开源 Distributed Configuration Management Platform(分布式配置管理平台) 统一管理配置
配置中心
包括 百度、滴滴打车、银联、网易、拉勾网 等知名互联网公司正在使用!

主要目标

  • 部署简单:同一个上线包,无须改动配置,即可在 多个环境中(dev/qa/pre/prod) 上线
  • 部署动态化:更改配置,无需重新打包或重启,即可 实时生效
  • 统一管理:提供web平台,统一管理 多个环境(dev/qa/pre/prod)、多个产品 的所有配置
  • 支持微服务架构

配置中心选型

  • 关于配置中心选型资料详见 《开源配置中心对比》

对接注意事项

  • httpclient 4.2.1以下的版本会报错, 推荐使用4.5.9 GA版本
  • 配置文件请保证配置正确性,如:配置项前后存在空格,配置格式,特殊字符,配置项编码等
  • spring5原client需重写ReloadingPropertyPlaceholderConfigurer类,super.parseStringValue 方法

SpringBoot对接

以下SpringBoot2 DisconfConfig 代码注入Bean配置对接方式可有效解决集成需要启动两次配置才生效的问题

1.  新建Disconf配置类DisconfConfig

import java.io.IOException;
import java.util.List;

import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baidu.disconf.client.DisconfMgrBean;
import com.baidu.disconf.client.DisconfMgrBeanSecond;
import com.baidu.disconf.client.addons.properties.ReloadablePropertiesFactoryBean;
import com.baidu.disconf.client.config.inner.DisInnerConfigAnnotation;
import com.baidu.disconf.client.support.DisconfAutowareConfig;
import com.google.common.collect.Lists;

/**
 * Disconf配置中心
 * @author ByWei.Cn
 * @date 2019/08/28
 */
@Configuration
public class DisconfConfig {

    @DisInnerConfigAnnotation(name = "disconf.scanpackage")
    public String scanpackage;
    
    @DisInnerConfigAnnotation(name = "disconf.locations")
    public String locations;
    
    public DisconfConfig() {
        super();
        try {
            DisconfAutowareConfig.autowareConfig(this, "disconf.properties");
        } catch (Exception e) {
        }
    }

    @Bean(destroyMethod = "destroy")
    public DisconfMgrBean disconfMgrBean() {
        DisconfMgrBean mgr = new DisconfMgrBean();
        mgr.setScanPackage(scanpackage);
        return mgr;
    }

    @Bean(initMethod = "init", destroyMethod = "destroy")
    public DisconfMgrBeanSecond disconfMgrBeanSecond() {
        return new DisconfMgrBeanSecond();
    }
    
    @Bean
    public ReloadablePropertiesFactoryBean reloadablePropertiesFactoryBean() {
        ReloadablePropertiesFactoryBean reloadProp = new ReloadablePropertiesFactoryBean();
        String[] props = locations.split(",");
        List propsList = Lists.newArrayList();
        for (String prop : props) {
            propsList.add("classpath:"+prop);
        }
        reloadProp.setLocations(propsList);
        return reloadProp;
    }

    @Bean
    public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer(ReloadablePropertiesFactoryBean reloadablePropertiesFactoryBean) {
        PropertyPlaceholderConfigurer prop = new PropertyPlaceholderConfigurer();
        prop.setIgnoreResourceNotFound(true);
        prop.setIgnoreUnresolvablePlaceholders(true);
        try {
            prop.setPropertiesArray(reloadablePropertiesFactoryBean.getObject());
        } catch (IOException e) {
             e.printStackTrace();
        }
        return prop;
    }
}

2.  在disconf.properties文件中新增自定义扩展配置

# scan package
disconf.scanpackage=cn.bywei.demo
# properties locations','split
disconf.locations=bywei-conf.properties

 

Disconf对接小技巧

  • 获取disconf配置项:DisClientConfig.getInstance().ENV
  • 多配置可通过自定义启动变量:
    xml获取- #{environment[‘project.channel’]} ;
    注解JAVA代码获取-DisconfConfig implements EnvironmentAware

HTTP Basic Authorization身份认证模式,抢先认证HttpClient 4.5.3 实例

Basic认证

关于HTTP BASIC认证

Basic 认证是服务器与客户端之间进行认证的一种方式,最初是在HTTP 1.0 规范(RFC 1945)中定义,后续的有关安全的信息可以在HTTP 1.1规范(RFC 2616)和HTTP认证规范(RFC 2617)中找到。HTTP Basic Authentication认证的服务,需要提供用户名和密码,否则服务器就会返回401。

HTTP BASIC认证流程原理

HTTP使用BASIC认证的原理是在HTTP协议进行通信的过程中,HTTP协议定义了基本认证过程以允许HTTP服务器对WEB浏览器进行用户身份认证的方法。
实现方法:当一个客户端向HTTP服务器进行数据请求时,如果客户端未被认证,则HTTP服务器将通过基本认证过程对客户端的用户名及密码进行验证,以决定用户是否合法。客户端在接收到HTTP服务器的身份认证要求后,会提示用户输入用户名及密码, 用户输入后,客户端将用户名和密码中间用“:”分隔合并,并将合并后的字符串用BASE64编码,在每次请求数据 时,将密文附加于请求头(Request Header)Authorization: Basic XXXXXXX中。HTTP服务器在每次收到请求包后,根据协议取得客户端附加的用户信息(BASE64编码的用户名和密码),解开请求包,对用户名及密码进行验证,如果用 户名及密码正确,则根据客户端请求,返回客户端所需要的数据;否则,返回错误代码或重新要求客户端提供用户名及密码。

JAVA HttpClient 4.5.3 抢先认证实例

原HttpClient 4.1.1 实例方法DefaultHttpClient等已过时废弃, 如下测试实例中,实现了两种方法:
1)通过HttpClient提供的抢先认证方式,直接跳过验证是否登录,把Basic Authorization信息发送给服务器
2)直接添加header的方式,HttpClient抢先认证方式原理同理

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Base64;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.AuthCache;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.entity.ContentType;
import org.apache.http.impl.auth.BasicScheme;
import org.apache.http.impl.client.BasicAuthCache;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
public class HttpsClientTest {

	@Test
	public void test_auth_basic_should_success() throws Exception {
		String url ="http://192.168.1.100:8080/bywei/api/authtest";
		HttpHost targetHost = new HttpHost("192.168.1.100", 8080, "http");
		HttpGet get = new HttpGet(url);
		UsernamePasswordCredentials credentials = new UsernamePasswordCredentials("test-auth", "=^ad.*sa:_2_RXa*23");
		
		// 使用 AuthCache 方式将使用RestClient 中的 MainClientExec方法,在发送请求时直接携带Authorization header信息
    	       AuthCache authCache = new BasicAuthCache();
    	       // Generate BASIC scheme object and add it to the local auth cache
    	      BasicScheme basicAuth = new BasicScheme();
    	      authCache.put(targetHost, basicAuth);
    	      // Add AuthCache to the execution context
    	      BasicHttpContext localcontext = new BasicHttpContext();
    	      localcontext.setAttribute(HttpClientContext.AUTH_CACHE, authCache);
		
		String content = doExecute(get, targetHost, credentials, localcontext);
		System.out.println("Authorization Basic认证authCache请求响应:"+content);
	}
	
	@Test
	public void test_auth_header_should_success() throws Exception {
		String url ="http://192.168.1.100:8080/bywei/api/authtest";
		HttpHost targetHost = new HttpHost("192.168.1.100", 8080, "http");
		HttpGet get = new HttpGet(url);
		String token = "test-auth:=^ad.*sa:_2_RXa*23";
		byte[] auth = Base64.getEncoder().encode(token.getBytes("UTF-8"));
		get.addHeader("Authorization", "Basic " + new String(auth));
		HttpClientContext context = HttpClientContext.create();
		String content = doExecute(get, targetHost, null, context);
		System.out.println("Authorization Basic认证header请求响应:"+content);
	}
	
	private CloseableHttpClient getHttpClient(UsernamePasswordCredentials credentials){
	    RequestConfig requestConf = RequestConfig.custom().setAuthenticationEnabled(false).build();
	    HttpClientBuilder httpClientBuilder = HttpClients.custom();
	    if(credentials != null) {
	    	CredentialsProvider provider = new BasicCredentialsProvider();
	    	provider.setCredentials(AuthScope.ANY, credentials);
	    	httpClientBuilder.setDefaultCredentialsProvider(provider);
	    }
	    CloseableHttpClient client = httpClientBuilder.setDefaultRequestConfig(requestConf).build();
	    return  client;
	}
	
	private String doExecute(HttpGet get, HttpHost targetHost, UsernamePasswordCredentials credentials, HttpContext contenxt) throws Exception {
		CloseableHttpResponse response = null;
		String content = "";
        try {
        	
        	//指定Client使用HttpContext,包含属性:http.auth.auth-cache
            response = getHttpClient(credentials).execute(get, contenxt);
            HttpEntity entity = response.getEntity();
            if(entity!=null) {
                Charset charset = ContentType.getOrDefault(entity).getCharset();
                content = EntityUtils.toString(entity, charset);
                EntityUtils.consume(entity);
                return content;
            }
        } catch(Exception ie) {
            ie.printStackTrace();
            throw ie;
        } finally {
            try {
                if(response!=null) {
                    response.close();
                }
            } catch(IOException e) {
            }
            if(get!=null) {
            	get.releaseConnection();
            } 
        }
        return content;
	}
}

截图去除水印软件-快捷键屏幕截图软件

最近企业微信最新发布了一个版本,突然发现在微信聊天背景上被悄然打上了水印标志。如果要是使用一般截图工具对聊天窗口截图,则会携带背景上的水印标志。遇到某种情况(你懂的!)将十分不方便。

业余时间做了下面的截图自动去掉水印的小工具,有需要的拿走吧!

截图自动去水印

特性介绍

截屏软件效果演示:

背景存在水印的企业微信聊天窗口

 

capturescreen截图后,生成的截屏无水印的图片

 

截图软件下载

截屏软件概要

  • 资源大小:1.44 MB
  • 月下载量:10,765 次
  • 软件属性:简体中文 免费软件
  • 更新时间:2019-05-09
  • 系统平台:Win10/Win7/WinVista/WinXP/Win2000/Win8 兼容软件
  • 官方网站:ByWei.Cn
  • 软件说明:截屏/截图/抓图自动去除图片背景水印,企业微信截图去水印,默认使用快捷键: Ctrl + Alt + A

截屏软件下载地址

  1. 推荐百度网盘下载:  链接: https://pan.baidu.com/s/1RZQP_FnfCokWmMqzyGJWkg   提取码:  vigc
  2. 百味博客官方下载

如何利用爬虫和小程序模板消息实现早报提醒

网络爬虫

当今社会通讯发达,大量资讯信息汇集,如何精准有效的获取最有价值的信息,也成为一项令人苦恼的事情。由此引发出通过大数据算法提取出最热点的信息的应用。百味博客致力于软件研发管理、互联网科技资讯、企业管理等领域研究学习。应博主及广大网友需求,特定制了“百味博客科技早报提醒”的功能。
百味博客使用的是经典的PHP程序 wordpress. 在开发早报功能前,需先安装wordpress插件“wp-json”, 该插件提供了rest的接口形式,以便直接对接早报功能。

一、抓取新闻数据

//待补充

二、分析热点、提炼

//待补充

三、WordPress存储

//待补充

四、小程序展示

//待补充

五、对接小程序模板消息

//待补充

六、定时发送早报提醒

//待补充

最终演示效果可以扫描下面二维码进入早报查看,或者在微信小程序栏搜索“百味博客”进入即可。

微信订阅号

API接口防恶意调用盗链或攻击方案

Web前后分离开发,防止API接口被恶意调用或攻击。度娘分享了很多种应对场景的方法。总结得比较好的见文章《前后端分离,如何防止API接口被恶意调用或攻击》、《如何防止别人恶意调用API接口》。
网络安全
本文选用了另外一种常见的配置下载防盗链机制的方法,使用该方式前请仔细阅读《彻底搞清referrer和origin》后,理解应用场景。具体操作记录如下:

  1. 增加Nginx端配置,使其能够获取到Http头信息Origin、Referer。
    proxy_set_header Origin $http_origin;
    proxy_set_header Referer $http_referer;
    
  2. 后端Java来源验证
    public static boolean originAuth(HttpServletRequest request) {
            String referer = request.getHeader("Referer");
            String origin = request.getHeader("Origin");
            String sitePart = request.getServerName();
            if(referer == null || origin == null) {
                return false;
            }
            if (referer != null && !referer.contains(sitePart)) {
                return false;
            }
            if (origin != null && !origin.contains(sitePart)) {
                return false;
            }
            return true;
        }
    

因Http协议是无状态的,针对上面的方法也不是完全无破解方案,只是提高了攻击者的难度。在这条接口网络安全的道路上还得持续的斗智斗勇。

免费图库WordPress插件开源分享

图片免费外链

百味免费图库插件

该插件让你直接在编辑器页面上传图片到免费服务器
上传完成后自动在编辑器中添加图片
功能简单方便

wordpress图片外链插件 wordpress图片外链插件 插件演示 插件演示

安装

  • 上传 free-picture-links目录 到 /wp-content/plugins/ 目录
  • 在后台插件菜单激活该插件
  • 在后台设置设置

开源地址

https://github.com/bywei/free-picture-links

其他百味博客开源项目:https://www.bywei.cn/github

关于作者

bywei = 程序员百味

个人博客 = “http://www.bywei.cn

用户协议

  • 禁止用户在使用中触犯中国法律范围内的任何法律条文。
  • 不通过出售任何以此项目为基础开发的产品,仅用作自身学习研究使用。
  • 任何个人,公司和组织不得以任何形式和目的侵犯百味博客的版权和著作权。
  • 在未经官方书面允许的情况下,任何个人、公司和组织不能单方面发布和出售以此项目为基础开发的任何互联网软件或者产品,否则将视为侵权行为,将依照中华人民共和国法律追究其法律责任。

ecshop聚合支付插件ipaynow现在支付

在使用ecshop中发现支付单独对接支付功能,开发成本高,微信支付,支付宝支付等都需要重新开发设计。百度发现现有聚合支付功能系统众多,特选用其中一个支付“现在支付”开发一ecshop支付插件。特分享!

现在支付支持功能如下

  • 互联网支付
    让你的网页具备银联支付、 银联快捷支付、微信支付、 支付宝支持、点卡和充值卡支付
  • 移动支付
    让你的移动应用具备银联支付、银联快捷支付、微信支付、 支付宝支持、点卡和充值卡支付
  • HTML5支付
    让你的移动网页具备银联支付、银联快捷支付、微信支付、支付宝支持、点卡和充值卡支付
  • 极简支付
    无需接入一行代码,只需创建应用,直接生成付款链接及付款二维码。
  • 扫码支付
    扫一扫二维码即可完成支付。

演示效果和安装步骤见后文

一、演示效果

ipaynow_ecshop聚合支付插件
ecshop商城购买商品- ipaynow_ecshop聚合支付插件
ipaynow_ecshop聚合支付插件
支付订单-ipaynow_ecshop聚合支付插件
ipaynow_ecshop聚合支付插件
ipaynow_ecshop聚合支付插件

二、安装步骤如下

1.下载ecshop插件现在支付ipaynow百度网盘地址:http://pan.baidu.com/s/1hr94sio

2.把对应压缩包解压到ecshop根目录

3.在ecshop后台安装‘现在支付’支付方式,填入现在支付appid,和key

4.前台查看展示,完毕!演示商城 奇趣坊 http://www.qiqufang.com

注意:介于时间精力有限,该插件并没有完整实现,如有相关需求可联系  微信 jiaivr

大型电商聚合支付架构系统源码 : https://www.bywei.cn/post/766.html

discuz大图压缩上传功能

前不久在给畅友365户外俱乐部搭建网站,发现很多爱好摄影的朋友在discuz论坛里面上传大量的摄影佳作时都会遇到一个问题:高清大图每个文件都差不多世纪兆,在使用discuz原上传图片功能时都会因为服务器的限制导致图片上传失败。因为discuz实现的方式是直接读取图片文件流上传到服务端,依赖服务端最大文件上传限制。

discuz这种上传确实令人头疼,特别针对使用discuz搭建摄影论坛的站长。

闲暇之余就自己制作了本地压缩上传大图的功能,特此分享。

演示地址:

http://www.ctrip365.com/thread-228-1-1.html

50个必备的实用jQuery代码段

本文会给你们展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助。其中的一些代码段是从jQuery1.4.2才开始支持的做法,另一些则是真正有用的函数或方法,他们能够帮助你又快又好地把事情完成。
1. 如何修改jQuery默认编码(例如默认UTF-8改成改GB2312):

$.ajaxSetup({
	ajaxSettings:{ contentType:"application/x-www-form-urlencoded;chartset=GB2312"}
});

2. 解决jQuery, prototype共存,$全局变量冲突问题:

<script src="prototype.js"></script>
<script src="http://blogbeta.blueidea.com/jquery.js"></script>
<script type="text/javascript">
      jQuery.noConflict();
</script>

注意:一定要先引入prototype.js 再引入jquery.js,先后顺序不可错。

3. jQuery 判断元素上是否绑定了事件

//jQuery event封装支持判断元素上是否绑定了事件,此方法只适用于jQuery绑定的事件
var $events = $("#foo").data("events");
if( $events && $events["click"] ){
  //your code
}

4. 如何使用jQuery来切换样式表

//找出你希望切换的媒体类型(media-type),然后把href设置成新的样式表。
$('link[media='screen']').attr('href', 'alternative.css');

5. 如何限制选择范围(基于优化目的):

复制代码
//尽可能使用标签名来作为类名的前缀,
//这样jQuery就不需要花费更多的时间来搜索
//你想要的元素。还要记住的一点是,
//针对于你的页面上的元素的操作越具体化,
//就越能降低执行和搜索的时间。
var in_stock = $('#shopping_cart_items input.is_in_stock');

<ul id="shopping_cart_items">
  <li><input type="radio" value="Item-X" name="item" /> Item X</li>
  <li><input type="radio" value="Item-Y" name="item" /> Item Y</li>
  <li><input type="radio" value="Item-Z" name="item" /> Item Z</li>
</ul>
复制代码

6. 如何正确地使用toggleClass:

//切换(toggle)类允许你根据某个类的
//是否存在来添加或是删除该类。
//这种情况下有些开发者使用:
a.hasClass('blueButton') ? a.removeClass('blueButton') : a.addClass('blueButton');
//toggleClass允许你使用下面的语句来很容易地做到这一点
a.toggleClass('blueButton');

7. 如何设置IE特有的功能:

if ($.browser.msie) {
// Internet Explorer就是个虐待狂
}

8. 如何使用jQuery来代替一个元素:

$('#thatdiv').replaceWith('fnuh');

9. 如何验证某个元素是否为空:

复制代码
// 方法一
if (! $('#keks').html()) {
//什么都没有找到;
}

// 方法二
if ($('#keks').is(":empty")) {
//什么都没有找到;
}
复制代码

10. 如何从一个未排序的集合中找出某个元素的索引号

$("ul > li").click(function () {
  var index = $(this).prevAll().length; //prevAll([expr]): 查找当前元素之前所有的同辈元素
});

11. 如何把函数绑定到事件上:

复制代码
//方法一
$('#foo').click(function(event) {
  alert('User clicked on "foo."');
}); 

//方法二, 支持动态传参
$('#foo').bind('click', {test1:"abc", test2:"123"}, function(event) {
  alert('User clicked on "foo."' + event.data.test1 + event.data.test2 );
});
复制代码

12. 如何追加或是添加html到元素中:

$('#lal').append('sometext');

13. 在创建元素时,如何使用对象字面量(literal)来定义属性

var e = $("", { href: "#", class: "a-class another-class", title: "..." });

14. 如何使用多个属性来进行过滤

//在使用许多相类似的有着不同类型的input元素时,
//这种基于精确度的方法很有用
var elements = $('#someid input[type=sometype][value=somevalue]').get();

15. 如何使用jQuery来预加载图像:

复制代码
jQuery.preloadImages = function() {
  for(var i = 0; i < arguments.length; i++) {
    $("<img />").attr('src', arguments[i]);
  }
};
//用法
$.preloadImages('image1.gif', '/path/to/image2.png', 'some/image3.jpg');
复制代码

16. 如何为任何与选择器相匹配的元素设置事件处理程序:

复制代码
$('button.someClass').live('click', someFunction);
//注意,在jQuery 1.4.2中,delegate和undelegate选项
//被引入代替live,因为它们提供了更好的上下文支持
//例如,就table来说,以前你会用
$("table").each(function(){
  $("td", this).live("hover", function(){
    $(this).toggleClass("hover");
  });
});
//现在用
$("table").delegate("td", "hover", function(){
  $(this).toggleClass("hover");
});
复制代码

17. 如何找到一个已经被选中的option元素:

$('#someElement').find('option:selected');

18. 如何隐藏一个包含了某个值文本的元素:

$("p.value:contains('thetextvalue')").hide();

19. 如何创建嵌套的过滤器:

//允许你减少集合中的匹配元素的过滤器,
//只剩下那些与给定的选择器匹配的部分。在这种情况下,
//查询删除了任何没(:not)有(:has)
//包含class为“selected”(.selected)的子节点。
.filter(":not(:has(.selected))")

20. 如何检测各种浏览器:

检测Safari (if( $.browser.safari)),
检测IE6及之后版本 (if ($.browser.msie && $.browser.version > 6 )),
检测IE6及之前版本 (if ($.browser.msie && $.browser.version <= 6 )),
检测FireFox 2及之后版本 (if ($.browser.mozilla && $.browser.version >= ’1.8′ ))

 

21. 任何使用has()来检查某个元素是否包含某个类或是元素:

//jQuery 1.4.*包含了对这一has方法的支持。
//该方法找出某个元素是否包含了其他另一个元素类或是其他任何的你正在查找并要在其之上进行操作的东东。
$("input").has(".email").addClass("email_icon");

22. 如何禁用右键单击上下文菜单:

$(document).bind('contextmenu',function(e){
  return false;
});

23. 如何定义一个定制的选择器

复制代码
$.expr[':'].mycustomselector = function(element, index, meta, stack){
// element- 一个DOM元素
// index – 栈中的当前循环索引
// meta – 有关选择器的元数据
// stack – 要循环的所有元素的栈
// 如果包含了当前元素就返回true
// 如果不包含当前元素就返回false };
// 定制选择器的用法:
$('.someClasses:test').doSomething();
复制代码

24. 如何检查某个元素是否存在

if ($('#someDiv').length) {
//万岁!!!它存在……
}

25. 如何使用jQuery来检测右键和左键的鼠标单击两种情况:

复制代码
$("#someelement").live('click', function(e) {
    if( (!$.browser.msie && e.button == 0) || ($.browser.msie && e.button == 1) ) {
        alert("Left Mouse Button Clicked");
    } else if(e.button == 2) {
        alert("Right Mouse Button Clicked");
    }
});
复制代码

26. 如何替换串中的词

var el = $('#id');
el.html(el.html().replace(/word/ig, ''));

27. 如何在一段时间之后自动隐藏或关闭元素(支持1.4版本):

//这是1.3.2中我们使用setTimeout来实现的方式
setTimeout(function() {
$('.mydiv').hide('blind', {}, 500)
}, 5000);
//而这是在1.4中可以使用delay()这一功能来实现的方式(这很像是休眠)
$(".mydiv").delay(5000).hide('blind', {}, 500);

28. 如何把已创建的元素动态地添加到DOM中:

var newDiv = $('<div></div>');
newDiv.attr('id','myNewDiv').appendTo('body');

29. 如何限制“Text-Area”域中的字符的个数:

复制代码
jQuery.fn.maxLength = function(max){
    return this.each(function(){
        var type = this.tagName.toLowerCase();
        var inputType = this.type? this.type.toLowerCase() : null;
        if(type == "input" && inputType == "text" || inputType == "password"){
            //Apply the standard maxLength
            this.maxLength = max;
        } else if(type == "textarea"){
            this.onkeypress = function(e){
                var ob = e || event;
                var keyCode = ob.keyCode;
                var hasSelection = document.selection? document.selection.createRange().text.length > 0 : this.selectionStart != this.selectionEnd;
                return !(this.value.length >= max && (keyCode > 50 || keyCode == 32 || keyCode == 0 || keyCode == 13) && !ob.ctrlKey && !ob.altKey && !hasSelection);
            };
            this.onkeyup = function(){
                if(this.value.length > max){
                    this.value = this.value.substring(0,max);
                }
            };
        }
    });
};
//用法
$('#mytextarea').maxLength(500);
复制代码

30. 如何jQuery注册和禁用jQuery全局事件

复制代码
//jQuery注册ajax全局事件ajaxStart,ajaxStop:
$(document).ajaxStart(function(){
    $("#background,#progressBar").show();
}).ajaxStop(function(){
    $("#background,#progressBar").hide();
});
//ajax请求禁用全局事件:$.ajax() 有个参数global (默认: true) 是否触发全局 AJAX 事件.设置为 false 将不会触发全局 AJAX 事件,如 ajaxStart 或 ajaxStop 可用于控制不同的 Ajax 事件。
复制代码

31. 如何在jQuery中克隆一个元素:

var cloned = $('#somediv').clone();

32. 在jQuery中如何测试某个元素是否可见

if($(element).is(':visible')) {
  //该元素是可见的
}

33. 如何把一个元素放在屏幕的中心位置:

复制代码
jQuery.fn.center = function () {
  return this.each(function(){
    $(this).css({
      position:'absolute',
      top, ( $(window).height() - this.height() ) / 2 + $(window).scrollTop() + 'px',
      left, ( $(window).width() - this.width() ) / 2 + $(window).scrollLeft() + 'px'
    });
  });
}
//这样来使用上面的函数:
$(element).center();
复制代码

 

34. 如何把有着某个特定名称的所有元素的值都放到一个数组中:

var arrInputValues = new Array();
$("input[name='xxx']").each(function(){
  arrInputValues.push($(this).val());
});

35. 如何从元素中除去HTML

复制代码
(function($) {
$.fn.stripHtml = function() {
  var regexp = /<("[^"]*"|'[^']*'|[^'">])*>/gi;
  this.each(function() {
    $(this).html( $(this).html().replace(regexp,'') );
  });
  return $(this);
}
})(jQuery);
//用法:
$('p').stripHtml();
复制代码

36. 如何使用closest来取得父元素:

$('#searchBox').closest('div');

37. 如何使用Firebug和Firefox来记录jQuery事件日志:

复制代码
// 允许链式日志记录
jQuery.log = jQuery.fn.log = function (msg) {
  if (console){
    console.log("%s: %o", msg, this);
  }
  return this;
};
// 用法:
$('#someDiv').hide().log('div hidden').addClass('someClass');
复制代码

38. 如何强制在弹出窗口中打开链接:

复制代码
$('a.popup').live('click', function(){
  var newwindow = window.open($(this).attr('href'),'','height=200,width=150');
  if (window.focus) {
    newwindow.focus();
  }
  return false;
});
复制代码

39. 如何强制在新的选项卡中打开链接:

$('a.newTab').live('click', function(){
  var newwindow=window.open(this.href);
  $(this).target = "_blank";
  return false;
});

40. 在jQuery中如何使用.siblings()来选择同辈元素

复制代码
// 不这样做
$('#nav li').click(function(){
  $('#nav li').removeClass('active');
  $(this).addClass('active');
});
//替代做法是
$('#nav li').click(function(){
  $(this).addClass('active').siblings().removeClass('active');
});
复制代码

41. 如何切换页面上的所有复选框:

var tog = false;
// 或者为true,如果它们在加载时为被选中状态的话
$('a').click(function() {
  $("input[type=checkbox]").attr("checked",!tog);
  tog = !tog;
});

42. 如何基于一些输入文本来过滤一个元素列表:

//如果元素的值和输入的文本相匹配的话,该元素将被返回
$('.someClass').filter(function() {
  return $(this).attr('value') == $('input#someId').val();
})

43. 如何获得鼠标垫光标位置x和y

$(document).ready(function() {
  $(document).mousemove(function(e){
    $(’#XY’).html(”X Axis : ” + e.pageX + ” | Y Axis ” + e.pageY);
  });
});

44. 如何扩展String对象的方法

复制代码
$.extend(String.prototype, {
        isPositiveInteger:function(){
            return (new RegExp(/^[1-9]\d*$/).test(this));
        },
        isInteger:function(){
            return (new RegExp(/^\d+$/).test(this));
        },
        isNumber: function(value, element) {
            return (new RegExp(/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/).test(this));
        },
        trim:function(){
            return this.replace(/(^\s*)|(\s*$)|\r|\n/g, "");
        },
        trans:function() {
            return this.replace(/&lt;/g, '<').replace(/&gt;/g,'>').replace(/&quot;/g, '"');
        },
        replaceAll:function(os, ns) {
            return this.replace(new RegExp(os,"gm"),ns);
        },
        skipChar:function(ch) {
            if (!this || this.length===0) {return '';}
            if (this.charAt(0)===ch) {return this.substring(1).skipChar(ch);}
            return this;
        },
        isValidPwd:function() {
            return (new RegExp(/^([_]|[a-zA-Z0-9]){6,32}$/).test(this));
        },
        isValidMail:function(){
            return(new RegExp(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/).test(this.trim()));
        },
        isSpaces:function() {
            for(var i=0; i<this.length; i+=1) {
                var ch = this.charAt(i);
                if (ch!=' '&& ch!="\n" && ch!="\t" && ch!="\r") {return false;}
            }
            return true;
        },
        isPhone:function() {
            return (new RegExp(/(^([0-9]{3,4}[-])?\d{3,8}(-\d{1,6})?$)|(^\([0-9]{3,4}\)\d{3,8}(\(\d{1,6}\))?$)|(^\d{3,8}$)/).test(this));
        },
        isUrl:function(){
            return (new RegExp(/^[a-zA-z]+:\/\/([a-zA-Z0-9\-\.]+)([-\w .\/?%&=:]*)$/).test(this));
        },
        isExternalUrl:function(){
            return this.isUrl() && this.indexOf("://"+document.domain) == -1;
        }
    });
复制代码

45. 如何规范化写jQuery插件:

复制代码
(function($){
    $.fn.extend({
        pluginOne: function(){
            return this.each(function(){
                // my code
            });
        },
        pluginTwo: function(){
            return this.each(function(){
                // my code
            });
        }
    });
})(jQuery);
复制代码

46. 如何检查图像是否已经被完全加载进来

$('#theImage').attr('src', 'image.jpg').load(function() {
  alert('This Image Has Been Loaded');
});

47. 如何使用jQuery来为事件指定命名空间:

//事件可以这样绑定命名空间
$('input').bind('blur.validation', function(e){
  // ...
});
//data方法也接受命名空间
$('input').data('validation.isValid', true);

48. 如何检查cookie是否启用

复制代码
var dt = new Date();
dt.setSeconds(dt.getSeconds() + 60);
document.cookie = "cookietest=1; expires=" + dt.toGMTString();
var cookiesEnabled = document.cookie.indexOf("cookietest=") != -1;
if(!cookiesEnabled) {
  //没有启用cookie
}
复制代码

49. 如何让cookie过期:

var date = new Date();
date.setTime(date.getTime() + (x * 60 * 1000));
$.cookie('example', 'foo', { expires: date });

50. 如何使用一个可点击的链接来替换页面中任何的URL

复制代码
$.fn.replaceUrl = function() {
  var regexp = /((ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?)/gi;
  return this.each(function() {
    $(this).html(
      $(this).html().replace(regexp,'<a href="$1">$1</a>')
    );
  });
}
//用法 
$('p').replaceUrl();
复制代码

host文件智能管理修改切换host工具_HostHelper_V1.4

简介

host文件智能管理修改切换host工具_HostHelper_V1.4
host文件修改工具,该软件能自动修改host文件,管理host指向记录。hostHelper经历了前面几个小版本,功能逐渐的增强。使做开发和测试工作的朋友节省了工作时间,提高了工作的效率,希望能为大家受用。
hosthelper
小工具要做就要能实实在在的做出小工具的特点。简单方便好用即可,HostHelper_V1.4增强了一点功能。能满足大部分的需求。

使用方法

1.下载 ‘HostHelper v1.1’(csdn,程序员百味 官网,51cto 均有下载地址),解压后,移动.exe可执行文件到自己的工作目录,建议不要放到桌面。
2.双击运行后,文件会自动生成两个文件,一个icon和一个配置文件(运行时,可能会有杀毒软件提示修改host或者开机项,请放心使用 并无病毒)
3.初次使用配置文件为空,请在’host管理’中点击‘配置文件格式’即可查看配置样式。
4.按照所需配置host,完毕点击保存。(注意:分组名即为托盘图标的菜单名,不可重复)
5.右键点击右下角host助手托盘图标,单击组可以设置包含子菜单的所有host,单击子选项,可配置单个host选项。
6.该版本可以配置小的选项(主配置),也可以配置更多的地址,方便与更高需求。

HOST助手 升级记录

HostHelper v1.0   完全自主配置 切换Host

HostHelper v1.1  修复开机自动运行时无法读取原配置文件
注意:
(1)V1.0升级时需要删除原来的自动运行注册表值
(2)如无法删除注册表值,请用新文件覆盖V1.0文件

HostHelper v1.2  修改了示例提示及部分异常提示信息

HostHelper v1.3  对代码进行简单的优化(稳定)

HostHelper v1.4  增强了功能,可配置单独文件(便于大量的host指向)

下载地址(各平台总计下载超1万次)

51cto http://down.51cto.com/data/550216

百度网盘 http://pan.baidu.com/share/link?shareid=155572&uk=1225960527

技术支持

程序员百味 QQ:1940775885
技术博客 http://www.bywei.cn/