当前位置

AMP表单Post方式提交后不能跳转的问题及解决办法

James Qi 在 2017年9月19日 - 16:02 提交
内容摘要:AMP (Accelerated Mobile Pages, 加速移动网页) 相关的改造工作我们已经进行了几个月,有相当一部分网站流量和广告收入转到AMP上面来了,应该来说还是很见成效的。不过有个技术......

  AMP (Accelerated Mobile Pages, 加速移动网页) 相关的改造工作我们已经进行了几个月,有相当一部分网站流量和广告收入转到AMP上面来了,应该来说还是很见成效的。不过有个技术问题一直没有解决,就是一些包含表单的页面,用Post方式提交后没有反应,不像对应的Web页面那样跳转到指定页面。

  Drupal网站中的站内搜索就是使用的Post方式提交搜索表单,我们就改为自己新建一个以Get方式提交的表单来替换,这样是可以跳转到指定搜索结果页面的,算是一种可行的替代办法。

  但像联系我们或者页面留言这一类的表单,内容比较复杂,就没法改为用Get方式提交了,这个问题就一直拖到现在,好几位同事摸索一阵子也没有结果。

  上周再和同事花了一些时间,专门一起来查看、调试,一点点排查,最后终于是试验出来可以跳转了,真是费尽千辛万苦!关键点如下:

  • 首先是需要把普通表单替换为符合AMP-Form的格式,特别是Post到的网址需要是action-xhr,这一步我们先已经实现了;
  • 后来发现在amp-form官方文档中有专门讲Redirect的部分我们忽略了,需要页面Header中使用AMP-Redirect-To来跳转;
  • 但我们按照这个在页面中加入相应的Header语句,也无法实现跳转,再在Google中搜索“amp form post redirect”等关键词,找到了几篇别人的问答,把示例代码复制出来,做了一个包含表单的html文件和一个进行处理的php文件,这样可以实现跳转,再精简其中语句,最后终于找到必须保留的几行(见本文底部);
  • 再来修改Drupal网站中includes/common.inc中的drupal_goto函数,不同的theme对应不同的跳转办法,终于可以在Drupal中实现需要的跳转效果了;
  • 不过直接修改Drupal的核心文件不合适,再在自定义模块中使用hook_drupal_goto_alter钩子函数,才算是完美实现了amp页面的表单post提交跳转!

  后来也实现了百度MIP的表单提交正确跳转,这个在后面的博文《使用drupal_goto_alter来替换百度MIP表单Post提交后跳转网址》中再记录。

$server_name = $_SERVER['SERVER_NAME'];
header("AMP-Access-Control-Allow-Source-Origin: https://$server_name");//这句不能少,允许跳转来源域名
header("AMP-Redirect-To: $url?amp");//这句不能少,指明跳转到的网址
header("Access-Control-Expose-Headers: AMP-Redirect-To, AMP-Access-Control-Allow-Source-Origin,Access-Control-Allow-Origin");//这句不能少,允许一些控制和跳转办法
header("location: $url");//同事发现https://jamesqi/node/333?amp这样的别名跳转出现问题,增加这句后解决
echo json_encode(array(""));//这句不能少,必须返回一个json数据,原因不明
die();//这句也不能少,原因不明

  我在上面代码中做了点注释,其实有些语句或者机制我也没有完全明白,反正是这样就可以实现。


   2017-10-31补充,实际实施的时候还可能遇到各种问题:

  如果开启了Honeypot并且默认启用了一个陷阱url的表单项(来引诱填表机器人填写以鉴别和屏蔽垃圾信息),在Web版本上看不到这个,但在amp版本中会看到标题为Leave this field blank的输入框,需要修改css来不显示,具体是../sites/all/themes/amptheme/ampsubtheme_example/css/amp-custom-styles.css中添加:

.url-textfield {
  display:none;
}

  如果amp验证还有报错The attribute 'action' may not appear in tag 'FORM [method=POST]',那就是表单替换这一步还没有实现,需要修改page.tpl.php,添加正则表达式替换:

        $pattern = "/<form class=\"([^\"]*)\" action=\"([^\"]*)\" method=\"post\" /";
        $replace = "<form class=\"$1\" action-xhr=\"$2\" method=\"post\" target=\"_top\" ";
        $output = preg_replace($pattern,$replace,$output);

        $pattern = "/<form action=\"([^\"]*)\" method=\"post\" /";
        $replace = "<form action-xhr=\"$1\" method=\"post\" target=\"_top\" ";
        $output = preg_replace($pattern,$replace,$output); 

  另外,如果调试contact联系功能的表单时遇到“系统设定 1 小时 内最多发送 5 条消息。请稍后再试。”,可以修改数据库中的variable表,将contact_threshold_limit从默认的5改为20或者其它你希望的数字,也可以用drush vset contact_threshold_limit xx来设置。

   contact表单提交后跳转到首页,但匿名用户没有显示“你的信息已被送出。”(管理员是显示的,我在amp版本的page.tpl.php中也打开了print $messages),暂未查明原因(可能是可能导致显示给其它匿名用户了)。