关于浏览器对于html的input标签中name的命名特殊字符处理(GET)与script+js跨域实现

因为想使用script来跨域GET提交数据回调,为了尽量的少改动,想到使用php的ob_start();这样的方式来缓存输出到变量中再进行jscall,即可解决可控网站的跨域问题,
不用重复实现,且性能上比服务类代理好得多.
然后想到应该使用某些不常用的命名来使用传递必须的数据,如post变get时,使用某特殊命名来传递之类考虑,于是看了一下这个问题.


http://www.w3.org/TR/html401/types.html#type-cdata中的规范规定是如下:

 ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

浏览器实测:


chrome



firefox

ie

op





看来标准中提到的写法还是都支持的.



实现的关键文件

jsCallBack.php

<?php
/*
 * 使用script标签的js回调的方式调用
 * 因为需要js配合GET方式来使用,所以使用特殊的get时的命名,如post转get时
 * name格式是[A-Za-z]开头,同时允许[0-9],"_","-",":"
 * f:=要运行php名字&c:=jsCallBack名字&p:其它字符=含有此前缀的变量都将转成POST变量,并删除get中的变量
 * 在source\class\helper\helper_form.php中来源检查
 */
header('Content-Type: text/html; charset=UTF-8');
define('DX_ROOT', str_replace("\\", '/', dirname(__FILE__)).'/');
$phps = array('forum', 'group', 'home', 'index', 'member', 'misc');//允许使用的php文件    
if (empty($_GET['f:']) or !in_array($_GET['f:'], $phps)) exit('alert("xxx.php?f:=the_php_file_name or no allow");');
if (empty($_GET['c:'])) exit('alert("xxx.php?c:=js_call_back_func_handled");');
require_once (DX_ROOT."/chrd.func.php");
if (!myDomain()) exit('alert("don\'t allow");');//只允许同根域名提交,不允许外站提交
unset($_SERVER['HTTP_REFERER']);//已经校验过,如果给dx检验,只允许同子域,所以清空
$_SERVER['REQUEST_METHOD'] = 'POST';//防止不允许GET;

foreach ($_GET as $key => & $val) {
	if (0 == (strncasecmp('p:', $key, 2))) {//处理post2get
		$_POST[substr($key, 2)] = $val;//注意传入时,会移除p:
	}
}

echo $_GET['c:'];//测试中发现无法此值放入create_function体内,总会自动变成null,而其它$_GET值却不会,奇怪,没细查
ob_start(create_function('$buf', 'return "(" .json_encode($buf). ");";'));
require (DX_ROOT."{$_GET['f:']}.php");
ob_end_clean();



某js

_.gJson({//dx/source/function/function_core.php中的submitcheck方法,允许flash提交
        url:forumUrl + 'jsCallBack.php?f:=forum&mod=post&action=reply&replysubmit=yes&infloat=yes&handlekey=fastpost&inajax=1'
        ,data:{//以下值需要post方式提交,所以,使用特殊方式
            'p:formhash':_.dxFormHash //form的hash值
            ,'p:message':_('answerMsg').value
            ,'p:seccodeverify':_('answerVerify').value //验证输入
            ,'p:sechash':_.dxCodeHash //验证hash值
            ,'p:subject':''
            ,'p:fid' : _('answerFid').value 
            , 'p:tid' : _('answerTid').value
        }
        ,fVar:'c:'//jscallback名字,gjson会自动生成一个全局的function句柄
        ,func:function(data) {	//jscallback 实现
			data = data.match(/<script[^>]*>(.+?)<\/script>/);
			var hideWindow = function(){};
			var showDialog = function(txt){_.showMaskDiv({htm:txt });};
			var succeedhandle_fastpost = function (url, tip, obj) {//dx发送成功的接口		
                    //('forum.php?mod=viewthread&tid=39&pid=121&page=1&extra=page%3D1#pid121', '非常感谢,回复发布成功,现在将转入主题页,请稍候……[ 点击这里转入主题列表 ]', {'fid':'2','tid':'39','pid':'121','from':'','sechash':'SU01yqk0'});
                        
				_.showMaskDiv({htm:'<a href="' +forumUrl+url+ '">'+ tip+'</a>', bind:{id:'answerSubmit'}});
				var div = document.createElement('P');
				div.innerHTML = _('answerMsg').value ;
				_('answerInsert').appendChild(div);
				_('answerReset').click();
			}
			var errorhandle_comment = function (tip) {//dx发送失败的接口
				_.showMaskDiv({htm:'发送失败<br/>' + tip});
			}
			if (!data) return showDialog('提交完成');
			try{eval(data[1]);}catch(e){showDialog('解析返回信息出错:<br/>' + (e.description ? e.description : e));} 		          
        }
    });

以上二个文件配合下,就可以向discuz进行跨提交而无需再修改dx的返回方式,

script 的src大概是如下

http://bbs.qidizi.net/jsCallBack.php?f:=forum&mod=post&action=reply&comment=yes&page=1&commentsubmit=yes&infloat=yes&inajax=1&&p:formhash=d9546afe&p:handlekey=comment&p:message=dddddddddddddddddddddddddddddd&p:seccodeverify=dddddddddddddddddddddddddddddddddd&p:sechash=0&p:tid=720564&p:pid=3370691&c:=_gJson21364554034648



那么返回就是正常的js了


_gJson21364554034648("<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<root><![CDATA[<script type=\"text\/javascript\" reload=\"1\">if(typeof succeedhandle_comment=='function') {succeedhandle_comment('forum.php?mod=viewthread&tid=720564&pid=3370691&page=1&extra=#pid3370691', '\u5e16\u5b50\u70b9\u8bc4\u6210\u529f ', {'tid':'720564','pid':'3370691'});}<\/script>]]><\/root>");


这样,只要在discuz目录下旋转一个jsCallBack.php文件

然后就可以在其它地方使用script方式伪ajax了.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值