[SiteLog]2015年5月6月回顾

每年的5月、6月总是很忙~ 回顾一下 Blog 情况,主要体现在以下:

  1. 网站对于 IE8/7/6 的兼容。
    从后台来看,来访的朋友中 IE8 还是占很大比例(也是,XP系统最大支持到IE8), IE6 居然也占相当比例。。 (汗,IE6 也许是最长寿的浏览器版本? )
    我迁移到Win7平台很久了。没有注意现在的网站在IE8及以下居然有网页错位和 JS 错误? 特意检测了下,调整了CSS和JS,现在基本上在 IE6/7 下面没有大的错位和JS错误,IE8下所有功能正常。

  2. Perl學習手札 - Easun.org 镜像 的移动优化。
    重构了这本书的所有页面,在保证PC界面和原来基本相同的情况下,移动端实现了自适应,方便同好者移动端阅读。

  3. 彻底修复和解决了 QQ 登录的一系列问题。
    XX的腾讯, API写的回调地址和浆糊一样而且处处矛盾。只能猜测+测试,而每次改动还需要审核~
    其实解决的办法就是回调地址并不是API文档宣称的不加 http(s):// 的纯域名,而是必须加上 http(s)://的具体到脚本的全url 才可以。

  4. 对 Ajax 评论做了跨域处理。
    [SiteLog]JQ AJAX 跨子域Post再总结。 同时对 JS 脚本重写和闭包处理,以方便移植。同时,对于多说附件JS 也做了重写和闭包处理。

7月也许会继续优化网站, 自娱自乐莫过于此。 写下来做个记录。

--EOF--

[SiteLog]JQ AJAX 跨子域Post再总结 ,

为了配合 CDN 前台。 后台的域名改成了 mt.easun.org/cgi-bin。 之所以启用子域而不是独立域名,是因为同域不同子域间可以天然共享 cookie ,而MT的POST必须带有 cookie ,不然登录信息验证不过。

测试一下正常的POST,没有任何问题。cookie 由于 CookieDomain 为 .easun.org ,所以cookie信息正常传递给了 mt.easun.org 后台。

但是接下来用 JQ $.post 进行 AJAX POST 的时候,就出现跨域问题了。 如果是Get,很简单,可以参考我上篇( [JQ+Perl]JQ AJAX跨站请求HTML/JS页面内容总结 )解决之。 POST 就必须设置跨站请求了。

不想回归 iframe 。幸好服务器部分配置可以自己控制。在后台脚本目录建立 .htaccess,内容如下:

<IfModule mod_headers.c>
  Header set Access-Control-Allow-Credentials: true
  Header set Access-Control-Allow-Origin "http://easun.org"
</IfModule>

这下应该可以 $.post 了吧?

但是结果依然很悲哀,这次 POST 成功, 但是 JQ 并不传递 Cookie。导致身份认证出错。 Google之。发现跨域(包括子域), 如果要传递Cookie, JQ AJAX 还需要手动发送认证凭证,设置 withCredentials ,这样才会传递 Cookie.

根据这些信息。 重写 $.post$.ajax 模式,代码如下:

$.ajax({
 type: 'POST',
 cache:false,
 url: url,
 data: $("#comments-form").serialize(),
 success: function(data){
  if (f.preview.value =='1' ) { EasunisPreReturn(data);}
  else {EasunisPostReturn(JSON.parse(data));}
 },
 xhrFields: {  withCredentials: true  },
});
return false;

调试之,一切OK。

参考资料:

1.【前端笔记】使用ajax跨域withCredentials的作用

后记:

对于IE8,9 来说。JQ AJAX 跨子域Post 即使设置了上述也会失败。原因很奇葩,跨域提交需要使用 XDomainRequest 对象。

幸好有 JQ 插件 jQuery-ajaxTransport-XDomainRequest 可以解决。 在 $.ajax 前引入:

<!--[if lte IE 9]>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.3/jquery.xdomainrequest.min.js"></script>
<![endif]-->

同时,为了兼容出错信息,当$.ajax 失败的时候,设定正常方式POST。虽然这样界面乱了,但是保证功能正常。

error: function(){ f.submit();  }

--EOF--

[模板]MT下最简单的实现CSS压缩的办法 ,

MT下最简单的实现CSS压缩(优化)的办法

大家都知道。 CSS压缩可以给网站访问提速, 这个也是 Google Yahoo 等大网站对于网站优化提出的标注之一。
但是,CSS压缩对于网站开发者来说,也意味着可读性降低,也意味着需要保留两份代码,一份正常的可读性高的,一份压缩的的供网站使用。
对于业余站长,压缩CSS是个可爱又可恨的东西,需要第3方工具来完成。
其实,对于 MT 程序来说,利用一点点模板变通可以实现 CSS的自动压缩。
简单的来说就是利用 MT 模板 Tag 自身的几个全局过滤函数的过滤/替换功能:

  1. strip_linefeeds
    strip_linefeeds 很好理解,就是把Tag内所有的换行去掉,让他变成一行。 使用办法 <$MT:tag strip_linefeeds="1" $>

  2. strip
    strip 过滤则是用特定字符替换掉 Tag 内的就空白(1个或者多个连续空格),比如我要把这些空白替换成一个空格则是用 <$MT:tag strip=" " $>

  3. 正则方式regex_replace=["正则表达式匹配部分","要替换成的内容"]
    这是最强大的功能,我们用它来替换掉原始CSS 的注释部分。 当然为了表达式简单,我只替换/*[注释内容]*/ 方式,而不处理 //[注释内容] 样式,这个就需要你的原始CSS 的注释必须是 /*[注释内容]*/ 方式,而不是 //[注释内容],但是修改所有的 //[注释内容]/*[注释内容]*/ 并不是太繁琐的事情。如果要处理 //[注释内容]方式,必须在 strip_linefeeds 之前使用。我的使用办法 <$MT:tag regex_replace="/\/\*.+?\*\//g","" $>
    注意,正则表达式兼容 Perl 正则,但是只识别 /../模式。

  4. trim
    trim 很好理解,就是把Tag内开头和结尾的空白去掉。 使用办法 <$MT:tag trim="1" $>

[JQ+Perl]JQ AJAX跨站请求HTML/JS页面内容总结 ,

路杨有2个域名,easun.org easunlee.org 统统指向同一个地址。
而小站的 blog 主页 的分页获取是通过 jQuery 的AJAX完成的。 见抓图。
index_15_6_5.png

核心代码为自写。如下:

function ajax_get (url, mode,callback)
  {
   var sdiv = $("#search-results"); 
   if (!sdiv) return true; 
   $.ajax({ 
        url:url, 
        data: {'format':'js'}, 
         success: function(data){ 
             if ( data.error == null ){ 
                      if (mode == 'append')  sdiv.append(data.result.content);
                      else  sdiv.html(data.result.content); 
                      if (data.result.next_url) { next_url = data.result.next_url;  } 
                      else { $('#show-more').hide(); }  
                      return false; 
                   }else { location.href = url;return true;}                       
              }, 
              error:function(req, status, obj){ location.href = url; return true;}, 
              beforeSend: function(xh){  /*do sth before send*/   },   
              complete: function(xh){  /*do sth for complete*/    } , 
             }); 
     }

其中url 为本站后台地址,大致为:
http://easun.org/{path-to-mt}/mt-search.cgi?IncludeBlogs=2&archive_type=Index&template_id={main_index_tmp_id}&page={num}

加上format=js参数则为JSON结构, 返回的数据大致为

{"error":null,"result":{"next_url":"下一页的地址","content":"本页展示数据"}}

如果出错,则在本页面打开没有 format=js 参数的完整 HTML 版本。

但是,这个脚本还是有问题的。

如果以域名 http://easun.org/blog/ 访问,则毫无问题, 一旦用 http://easunlee.org/blog/ 则基本上不能完成。 不用说后期路杨打算给后台设置不同的子域名。
原因很简单: ajax 不能跨站。(当然某些BT 的 ie 版本正常跨站,汗。)

有没有办法解决这个问题呢?

研究了一番,发现使用 jQuery 的 JSONP 方式即可完成。
即让后台返回的数据为

mycallback( {"error":null,"result":{"next_url":"下一页的地址","content":"本页展示数据"}} );

当然需要修改核心代码,让 $.ajax 工作在 JSONP 下:

function ajax_get (url, mode,callback)
{
  var sdiv = $("#search-results"); 
  if (!sdiv) return true; 
  $.ajax({ 
        url:url, 
        data: {'format':'js'}, 
        dataType: "jsonp",  /*定义dataType*/
        jsonpCallback:"mycallback", /*定义jsop 回调函数*/
         success: function(data){ 
             if ( data.error == null ){ 
                      if (mode == 'append')  sdiv.append(data.result.content);
                      else  sdiv.html(data.result.content); 
                      if (data.result.next_url) { next_url = data.result.next_url; } 
                      else { $('#show-more').hide(); }  
                      return false; 
                   }else { location.href = url;return true;}                       
              }, 
              error:function(req, status, obj){ location.href = url; return true;}, 
              beforeSend: function(xh){  /*do sth before send*/   },   
              complete: function(xh){  /*do sth for complete*/    } , 
             }); 
}

不用担心返回的 JSONP 数据在 success: function(data) 中无法解析,只要定义了
dataType: "jsonp",jsonpCallback:"mycallback",success: function(data)中的 data 自动为 JSONP 中包含的 JSON数据。 而不是 JSONP 数据串。
现在的问题,是后台的 mt-search.cgi 不具备输出 JSONP 格式的能力, format=js 只能输出 JSON 格式,这个时候如果不想修改 mt 代码。则只能通过自己写的脚本(Perl)来中转了。

[多说]不本地化embed.js使多说评论显示UA ,

title.jpg

个性化 多说显示,让多说显示评论者的 UA,貌似教程很多。


比如: 我的那些事 - 多说回复后显示浏览器及操作系统信息(Useragent) 这里。


但是方案都是 本地化 embed.js 然后修改 embed.js 完成。

不想本地化 embed.js ,搜索了一下网络, 发现有不本地化 用 JS Hook 方式修改的办法,见
https://github.com/huhuime/make_duoshuo_show_ua

但是,根据这个修改后无效, 检测了多说的 embed.js 代码,发现是因为版本更新导致变量失效,修改 e.agent 为e.post.agent 即可。

简单整理如下。

在 多说 自己的 JS 导入后面的任意位置添加以下代码:

    <script type="text/javascript">
    if (typeof DUOSHUO !== 'undefined')hookDUOSHUO_tp();
    else $('[src="http://static.duoshuo.com/embed.js"]')[0].onload=hookDUOSHUO_tp;
    function hookDUOSHUO_tp(){
        var _D_post=DUOSHUO.templates.post
        DUOSHUO.templates.post=function (e,t){
            var rs=_D_post(e,t);
            var agent=e.post.agent;
            if(agent&&/^Mozilla/.test(agent))rs=rs.replace(/<\/div><p>/,show_ua(agent)+'</div><p>');
            return rs;
        }
    }
    function show_ua(string){
        console.log(string)
        $.ua.set(string);
        var sua=$.ua;
        if(sua.os.version=='x86_64')sua.os.version='x64';
        return '<span class="this_ua platform '+sua.os.name+'">'+sua.os.name+' '+sua.os.version+'</span><span class="this_ua browser '+sua.browser.name+'">'+sua.browser.name+'|'+sua.browser.version+'</span>';
    }
    </script>

第1页/共49页,加载更多