标签/Tag为[跨域]的文章

[SiteLog]全站 https 的尝试和MT相应修改

This is a sitelog of Easun.org.

ssltest of easun.org

貌似已经落伍了。。 看见大家的网站已经统统迁移到了 https ,也是,更安全貌似也更流行?

研究了一番,最后也图省事。 干脆在 腾讯云 上申请免费的 DV证书 并下载到自己的服务器完事,其过程乏味无趣,也就一笔略过。
配置完后上 https://www.ssllabs.com/ssltest/ 测试一下。达到 A+ 为宜。

[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,内容如下:

code<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 模式,代码如下:

code$.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 前引入:

code<!--[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。虽然这样界面乱了,但是保证功能正常。

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

--EOF--

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

路杨有2个域名,[easun.org](http://easun.org) [easunlee.org](http://easunlee.org) 统统指向同一个地址。
而小站的 [blog 主页](http://easun.org/blog) 的分页获取是通过 [jQuery](http://jquery.com/) 的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 版本。 ## 但是,这个脚本还是有问题的。 如果以域名 访问,则毫无问题, 一旦用 则基本上不能完成。 不用说后期路杨打算给后台设置不同的子域名。 原因很简单: **ajax 不能跨域**。(当然某些BT 的 ie 版本正常跨域,汗。) ###有没有办法解决这个问题呢? 研究了一番,发现使用 [jQuery](http://jquery.com/) 的 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)来中转了。