您的位置:首页 > 移动开发 > 微信开发

js replace 全局替换 以表单的方式提交参数 判断是否为ie浏览器 将jquery.qqFace.js表情转换成微信的字符码 手机端省市区联动 新字体引用本地运行可以获得,放到服务器上报404 C#提取html中的汉字 MVC几种找不到资源的解决方式 使用Windows服务定时去执行一个方法的三种方式

2018-06-26 20:37 2351 查看

js replace 全局替换

 

js 的replace 默认替换只替换第一个匹配的字符,如果字符串有超过两个以上的对应字符就无法进行替换,这时候就要进行一点操作,进行全部替换。

<script language="javascript">
var strM = "这是要被替换的字符串啊啊!";
//在此我想将字母a替换成字母A
alert(strM.replace("啊","额"));
</script>

上面这段代码,只能替换第一个字符“啊”,第二个“啊”就无法替换,这样就没办法满足大多数使用js(replace)的需求

<script type="text/javascript" language="javascript">
var s = "这是要被替换的字符换啊啊!";
alert(s);
alert(s.replace(/啊/g, "额"));

这样,就可以实现整个字符串的替换。

我们这里用到了正则函数的/g全部的使用。这样就可以实现整个字符串的替换效果。

下面,我们大家可能还有个需求无法满足,那就是,我们替换定值可以使用这个,但是替换变量怎么使用?

接下来,就说一下替换变量的使用方式。

简单介绍一下eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。接下来主要靠这个函数。

<script>
var ch = "变量";
var reg = "/"+ch+"/g";
var str = "这是一个变量,这是一个变量";
var val = str.replace(eval(reg),"替换");
alert(val);
</script>

但是如果要替换的字符串中含有/符号时,上面的就不能用了,需要采取以下方法

<script>
var ch = "/";
var str = "这是一/个变量,这是一个变量";
var val = str .replace(new RegExp(ch,'g'),"b");
alert(val);
</script>

 

以表单的方式提交参数

 

PostFromHelper 代码

public class FormItemModel
{
/// <summary>
/// 表单键,request["key"]
/// </summary>
public string Key { set; get; }
/// <summary>
/// 表单值,上传文件时忽略,request["key"].value
/// </summary>
public string Value { set; get; }
/// <summary>
/// 是否是文件
/// </summary>
public bool IsFile
{
get
{
if (FileContent == null || FileContent.Length == 0)
return false;

if (FileContent != null && FileContent.Length > 0 && string.IsNullOrWhiteSpace(FileName))
throw new Exception("上传文件时 FileName 属性值不能为空");
return true;
}
}
/// <summary>
/// 上传的文件名
/// </summary>
public string FileName { set; get; }
/// <summary>
/// 上传的文件内容
/// </summary>
public Stream FileContent { set; get; }
}
public class PostFromHelper
{
/// <summary>
/// 使用Post方法获取字符串结果
/// </summary>
/// <param name="url"></param>
/// <param name="formItems">Post表单内容</param>
/// <param name="cookieContainer"></param>
/// <param name="timeOut">默认20秒</param>
/// <param name="encoding">响应内容的编码类型(默认utf-8)</param>
/// <returns></returns>
public static string PostForm(string url, List<FormItemModel> formItems, CookieContainer cookieContainer = null, string refererUrl = null, Encoding encoding = null, int timeOut = 20000)
{
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
#region 初始化请求对象
request.Method = "POST";
request.Timeout = timeOut;
request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
request.KeepAlive = true;
request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
if (!string.IsNullOrEmpty(refererUrl))
request.Referer = refererUrl;
if (cookieContainer != null)
request.CookieContainer = cookieContainer;
#endregion

string boundary = "----" + DateTime.Now.Ticks.ToString("x");//分隔符
request.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
//请求流
var postStream = new MemoryStream();
#region 处理Form表单请求内容
//是否用Form上传文件
var formUploadFile = formItems != null && formItems.Count > 0;
if (formUploadFile)
{
//文件数据模板
string fileFormdataTemplate =
"\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"" +
"\r\nContent-Type: application/octet-stream" +
"\r\n\r\n";
//文本数据模板
string dataFormdataTemplate =
"\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\"" +
"\r\n\r\n{1}";
foreach (var item in formItems)
{
string formdata = null;
if (item.IsFile)
{
//上传文件
formdata = string.Format(
fileFormdataTemplate,
item.Key, //表单键
item.FileName);
}
else
{
//上传文本
formdata = string.Format(
dataFormdataTemplate,
item.Key,
item.Value);
}

//统一处理
byte[] formdataBytes = null;
//第一行不需要换行
if (postStream.Length == 0)
formdataBytes = Encoding.UTF8.GetBytes(formdata.Substring(2, formdata.Length - 2));
else
formdataBytes = Encoding.UTF8.GetBytes(formdata);
postStream.Write(formdataBytes, 0, formdataBytes.Length);

//写入文件内容
if (item.FileContent != null && item.FileContent.Length > 0)
{
using (var stream = item.FileContent)
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = stream.Read(buffer, 0, buffer.Length)) != 0)
{
postStream.Write(buffer, 0, bytesRead);
}
}
}
}
//结尾
var footer = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");
postStream.Write(footer, 0, footer.Length);

}
else
{
request.ContentType = "application/x-www-form-urlencoded";
}
#endregion

request.ContentLength = postStream.Length;

#region 输入二进制流
if (postStream != null)
{
postStream.Position = 0;
//直接写入流
Stream requestStream = request.GetRequestStream();

byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = postStream.Read(buffer, 0, buffer.Length)) != 0)
{
requestStream.Write(buffer, 0, bytesRead);
}

////debug
//postStream.Seek(0, SeekOrigin.Begin);
//StreamReader sr = new StreamReader(postStream);
//var postStr = sr.ReadToEnd();
postStream.Close();//关闭文件访问
}
#endregion

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
if (cookieContainer != null)
{
response.Cookies = cookieContainer.GetCookies(response.ResponseUri);
}

using (Stream responseStream = response.GetResponseStream())
{
using (StreamReader myStreamReader = new StreamReader(responseStream, encoding ?? Encoding.UTF8))
{
string retString = myStreamReader.ReadToEnd();
return retString;
}
}
}
}

使用方法

var formDatas = new List<FormItemModel>();
//添加文件
formDatas.Add(new FormItemModel()
{
Key = "media",
Value = "",
FileName = filename,
FileContent = File.OpenRead(filepath)
});
//提交表单
var result = PostFromHelper.PostForm(url, formDatas);

 

判断是否为ie浏览器

 
function isIE(){
var userAgent = navigator.userAgent,
rMsie = /(msie\s|trident.*rv:)([\w.]+)/,
rFirefox = /(firefox)\/([\w.]+)/,
rOpera = /(opera).+version\/([\w.]+)/,
rChrome = /(chrome)\/([\w.]+)/,
rSafari = /version\/([\w.]+).*(safari)/;
var browser;
var version;
var ua = userAgent.toLowerCase();

var match = rMsie.exec(ua);
if (match != null) {
ieVersion = { browser : "IE", version : match[2] || "0" };
return true;
}
var match = rFirefox.exec(ua);
if (match != null) {
var ffVersion = { browser : match[1] || "", version : match[2] || "0" };
return false;
}
var match = rOpera.exec(ua);
if (match != null) {
var opVersion =  { browser : match[1] || "", version : match[2] || "0" };
return false;
}
var match = rChrome.exec(ua);
if (match != null) {

var chVersion = { browser : match[1] || "", version : match[2] || "0" };
return false;
}
var match = rSafari.exec(ua);
if (match != null) {

var sfVersion = { browser : match[2] || "", version : match[1] || "0" };
return false;
}
if (match != null) {
var ohterVersion = { browser : "", version : "0" };
return false;
}
}

 

将jquery.qqFace.js表情转换成微信的字符码

 

jquery.qqFace.js使用方法

引用

<script src="~/Content/qqFace/js/jquery.qqFace.js?v=3"></script>
<script src="~/Content/qqFace/js/jquery-browser.js"></script>

html

<div style="width:50px;height:30px;margin-top:3px;text-align:center;line-height:30px;border-right:1px solid #dee5e7"><img src="~/Content/emoji.png" class="emotion" /></div>
<textarea class="input" id="saytext" name="saytext" style="display:none"></textarea>

初始化

$(function () {

$('.emotion').qqFace({
id: 'facebox',
assign: 'saytext', //给输入框赋值
path: '/Content/qqFace/arclist/' //表情图片存放的路径
});

});
原来的jQuery.qqface.js有下面这个方法

function replace_em(str) {

str = str.replace(/\</g, '&lt;');

str = str.replace(/\>/g, '&gt;');

str = str.replace(/\n/g, '<br/>');

str = str.replace(/\[em_([0-9]*)\]/g, '<img src="/Content/qqFace/arclist/$1.gif" border="0" />');

return str;

}

点击表情会把表情转换成图片保存到$("#saytext")里,我自己修改一下将表情在我们需要显示地方显示出来

//修改原来js
var str = $("#saytext").val().trim();

$("#show").append(replace_em(str));
$("#saytext").val('');

 

 

将表情转换成微信字符码,因为做微信自动回复时回复文本消息不能回复文字加图片,所以我对照网上的数据,将表情图片一一对应的字符码找出来

我自己拼的字符码,按照上面表情的顺序组合的,有的没找到吗直接用微信的文字表示,微信发出去收到的也可以转换成表情

 private string emoij = "/::);/::~;/::B;/::|;/::<;/::$;/::X;/::Z;/::’(;/::-|;/::@;/::P;/::D;/::O;/::(;/:–b;/::Q;/::T;/:,@P;/:,@-D;/::d;/:,@o;/::g;/:|-);/::!;/::L;/::>;/::,@;/:,@f;/::-S;/:?;/:,@x;/:,@@;/::8;/:,@!;/:xx;/:bye;/:wipe;/:dig;/:&-(;/:B-);/:<@;/:@>;/::-O;/:>-|;/:P-(;/::’|;/:X-);/::*;/:@x;/:8*;[拥抱];[月亮];[太阳];[炸弹];/:!!!;/:pd;/:pig;/:<W>;/:coffee;/:eat;/:heart;[强];[弱];[握手];[胜利];[抱拳];[勾引];[OK];[NO];/:rose;/:fade;/:showlove;[跳跳];[转圈]";

 

var emoijarray = emoij.Split(';');
int len = emoijarray.Length;
for (int i = 0; i < len; i++)
{
string str = string.Format("<img src={0}/Content/qqFace/arclist/{1}.gif{2} border={3}0{4}>",'"',i+1, '"', '"', '"');
if (xmlstr.Contains(str))//查找发送的文本消息中是否含有表情图片标签,有的话替换成对应的字符码,或许大家有更好的方式替换,我这只是循环去查找匹配的替换
{
xmlstr = xmlstr.Replace(str, emoijarray[i]);
}
}

这是微信上就可以收到表情了

 

手机端省市区联动

 

使用的插件为LArea

使用方法

<link href="~/Assets/js/5iweb2016073010/css/LArea.css" rel="stylesheet" type="text/css" />
<script src="~/Assets/js/5iweb2016073010/js/LAreaData1.js"></script>
<script src="~/Assets/js/5iweb2016073010/js/LAreaData2.js"></script>
<script src="~/Assets/js/5iweb2016073010/js/LArea.js"></script>
<input  type="text" value="" placeholder=""  id="txt_area" >
<input type="hidden" id="hd_area"/>
var area1 = new LArea();
area1.init({
'trigger': '#txt_area', //触发选择控件的文本框,同时选择完毕后name属性输出到该位置
'valueTo': '#hd_area', //选择完毕后id属性输出到该位置
'keys': {
id: 'id',
name: 'name'
}, //绑定数据源相关字段 id对应valueTo的value属性输出 name对应trigger的value属性输出
'type': 1, //数据源类型
'data': LAreaData //数据源
});

出现的问题:点击input时会默认弹出软件盘,与插件弹出的省市区选择器重叠

解决办法:

$("#txt_area").focus(function () {
document.activeElement.blur();
});

或者

<inputtype="text" value="" placeholder=""  id="txt_area" onfocus="this.blur();"/>

插件地址http://www.5iweb.com.cn/page-useful-effects/723.html

 

新字体引用本地运行可以获得,放到服务器上报404

 

背景:做一个手机页面,运用到了一个新的字体(造字工房映力黑规体),ui给我一个otf格式的字体文件,本地通过一下方式引用

@font-face {
font-family: '造字工房映力黑规体';
src: url(@(Url.Content("~"))Assets/fonts/font-zzgf.otf);
}

问题:本地运行没有问题,字体可以正常显示,但是放到服务器上报404错误,一开始我以为是我路径有问题,对照了好几次,发现路径没有问题,命名也没有问题

解决办法:最后百度发现是iis默认不认识otf的文件

打开iis,找到部署的网站,点击MIME类型,点击右侧添加新的类型

 

 

 

最后点击确定刷新页面就可以了

 

C#提取html中的汉字

 
using System.Text.RegularExpressions;

private string StripHT(string strHtml)  //从html中提取纯文本
{
Regex regex = new Regex("<.+?>", RegexOptions.IgnoreCase);
string strOutput = regex.Replace(strHtml, "");//替换掉"<"和">"之间的内容
strOutput = strOutput.Replace("<", "");
strOutput = strOutput.Replace(">", "");
strOutput = strOutput.Replace("&nbsp;", "");
return strOutput;
}

 

 

 

MVC几种找不到资源的解决方式

 

在MVC中,controller中的Action和View中的.cshtml文件名称有一个对应的关系。

当不对应时,有以下几种情况发生:

一、找不到视图的错误

请求URL:http://localhost:13850/Customer/Create

controller中有对应的Action:

View中没有相应的视图

报错信息:

解决方式:在View中添加相应的View

二、找不到资源:

请求的URL:http://localhost:13850/Customer/Index

controller里没有相应的Action(有时候可能是在开发一段时间以后,修改了Action的名字,却没有相应的修改View的名字,但是请求的URL依然还是原来的导致的)

View里有相应的视图

错误信息:

解决方式,就是指定一个固定的“页”,在找不到资源时显示。具体如下:

Asp.Net MVC中的controller都是集成自Controller这个抽象类,在这个类中,定义了一个HandleUnknownAction 方法,左右就是在发生HTTP 404时,进行处理。

那么,我们可以在自己的controller里重写这个方法。

这样,在每次找不到相应的Action时,都能执行这个方法。去调用相应的View。

微软提供的方式是:

protected override void HandleUnknownAction(string actionName)

 {    

    try {        

        this.View(actionName).ExecuteResult(this.ControllerContext);    

      } catch (InvalidOperationException ieox )

      {        

         ViewData["error"] = "Unknown Action: \"" +Server.HtmlEncode(actionName) + "\"";        

         ViewData["exMessage"] = ieox.Message;        

         this.View("Error").ExecuteResult(this.ControllerContext);    

      }

}

也就是,输出错误页。

当然这也存在一个隐患,如果出现下面【三】的情况时,也就是只声明了一个HTTP.Post的方法,没有相应的Http.Get的同名方法,也能把通过这种方式,把页面加载出来。

怎么解决呢?答案就是:直接Response.Redirect("/",true),回到首页。

三、找不到资源:

请求URL:http://localhost:13850/Customer/Details

controller中的对应Action,定义为HTTP Post,且没有对应的Http Get的Action

View中有对应的视图

报错信息:

解决方式:加入一个同名Action,定义为HTTP GET:[AcceptVerbs(HttpVerbs.Get)]

 

四:这是我今天遇到的找半天没找到原因,最后看http://www.cnblogs.com/xyang/archive/2011/11/24/2262003.html才发现的

 

备注,感谢http://www.cnblogs.com/xyang/archive/2011/11/24/2262003.html提供的解决办法

 

使用Windows服务定时去执行一个方法的三种方式

 

方式一:使用System.Timers.Timer定时器

public partial class Service1 : ServiceBase
{

private UnitOfWork unitOfWork;
private System.Timers.Timer timer1;//初始化一个定时器
LogHelper lghelper = new LogHelper(typeof(Service1));
public Service1()
{
InitializeComponent();
unitOfWork = new UnitOfWork();
this.timer1 = new System.Timers.Timer();
this.timer1.Interval = 1000;//设置定时器启动的时间间隔
this.timer1.Elapsed += new System.Timers.ElapsedEventHandler(timer1_Elapsed);//定时器定时执行的方法
}

protected override void OnStart(string[] args)
{
this.timer1.Enabled = true;//服务启动时开启定时器
lghelper.Info("服务启动");
}

protected override void OnStop()
{
this.timer1.Enabled = false;//服务停止时关闭定时器
unitOfWork.Dispose();
lghelper.Info("服务停止");
}

private void timer1_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
this.timer1.Enabled = false;//在服务运行时关闭定时器,避免在服务还没有运行结束时达到定时器时间间隔又重头开始运行(比如该定时器设置为5分钟同步一次数据,当数据量很大时,5分钟同步不完,这时达到定时器时间间隔,又会重头开始同步,所以在服务开始运行时关闭定时器)
lghelper.Info("服务开始运行");
try
{

DoWork();
}
catch (Exception ex)
{
lghelper.Error(ex.ToString());
lghelper.Info("服务运行失败");
Thread.Sleep(5000);
}

this.timer1.Enabled = true;//服务运行结束,重新启动定时器
}

}

方式二:使用Task

partial class Service2 : ServiceBase, IDisposable
{
LogHelper lghelper = new LogHelper(typeof(Service2));
private CancellationTokenSource TokenSource = new CancellationTokenSource();
protected UnitOfWork unitOfWork = new UnitOfWork();

Task MainTask;
public Service2()
{
InitializeComponent();

}
public void Dispose()
{
unitOfWork.Dispose();
}

protected override void OnStart(string[] args)
{
lghelper.Info("开启服务!");
MainTask = Task.Factory.StartNew(() =>
{
while (true)
{
try
{
DoWork();

}
catch (Exception ex)
{
lghelper.Error(ex.ToString());

Thread.Sleep(60 * 60 * 1000);
}

Thread.Sleep(5 * 60 * 1000);
}

});

}

protected override void OnStop()
{
if (MainTask != null)
{
if (MainTask.Status == TaskStatus.Running) { }
{
TokenSource.Cancel();
lghelper.Info("线程结束");
}
}
}

}

方式三:这个方法是看到博友的,还没有用过,不过觉得挺方便的

http://www.cnblogs.com/ldyblogs/p/timer.html

神奇的Timer

 

最近的一个项目有一些地方需要用到定时功能,在设计过程中,突然发现.net的Timer类居然还有很多我以前没有用过的功能,这里就跟大家分享一下

注:这里的Timer类特指System.Threading.Timer类

情景1:我需要服务器在每天的00:00点执行一个操作

我当开始想到的方法很2b,居然是设定定时器每个1分钟去检查时间,如果当前时间与00:00相差不超过1分钟时,就执行操作!!!由于这段的代码太过2b,所以就不放上来了!

我都不知道自己刚开始怎么会想到如此2的设计,几乎刚把代码写完我自己就把这个方案个否定了,极度浪费资源不说,还不能精准的在00:00执行操作!

于是我又一次查看了msdn,msdn真是编程神器啊,现在我离开了它简直是寸步难行了,我惊喜的发现Timer的构造函数中有这样一个参数

这个dueTime参数不正是我需要的吗?只不过我以前一般忽略了这个参数,直接将其置为0了!所以我立刻写下了下面的代码

var span = DateTime.Today.AddDays(1) - DateTime.Now;
var timer = new Timer(callback, null, (int)span.TotalMilliseconds, 24 * 3600 * 1000);

于是在第二天的00:00,定时器就开始执行,然后每隔24小时执行一次,这样就完美的达到了情景中的目标!

情景2:我需要每个5分钟保存一次RichTextBox中的内容

这实际上就是一个类似Word的自动保存功能,刚开始我觉得很简单,不就是定义一个5分钟的定时器就了事吗?后来想想不这么简单,因为如果用户不在RichTextBox更改任何内容,这是还是隔5分钟保存一次就是资源浪费!于是可以将上述情景更加精确的描述为:

在用户每次对RichTextBox的内容修改之后的5分钟时,对RichTextBox中内容保存一次!

这样又如何去实现呢?于是我又一次查看了MSDN,果然没让我失望,MSDN又一次给了我惊喜,请看下面的MSDN说明

这句话简直就是为了解决情境中的问题说的啊!于是我立刻写下了下面的代码:

System.Threading.Timer timer = null;
bool needSave = false;
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
if (timer == null)
timer = new System.Threading.Timer(Callback, null, 5 * 60 * 1000, 0);
else if (needSave)
{
needSave = false;
timer.Change(5 * 60 * 1000, 0);
}
}
void Callback(object state)
{
Save();
needSave = true;
}
将period参数置为0,就意味着定时器只会执行一次,此时定时功能是依靠参数dueTime来实现的,Change函数可以重启定时功能,并且每次RichTextBox中有内容的改变,定时器就会被重置,这样就完美的解决了情境中的问题了!

 

以上图片由“博客园”提供

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐