PHP区分javascript和用户点击?

Posted

技术标签:

【中文标题】PHP区分javascript和用户点击?【英文标题】:Php differentiating between javascript and user click? 【发布时间】:2019-09-02 17:55:26 【问题描述】:

我将 javascript 注入 php 网站以避免弹出窗口,以自动提交表单。另外,jquery 存在问题,所以我使用的是纯 javascript。

这是页面上的表格:

<form action='http://mywebsite.com/index.php?&act=MYFUNCTION&CODE=01&CookieDate=1' name='subscribe_check' method='POST'>
<input type='hidden' name='value1' value='dynamicallygenerated'>
<input type='hidden' name='Value2' value='BlogSection'>
<input type='hidden' name='Value3' value='BlogName'>
<select class='forminput' name='sub_id' onchange='this.form.submit()'>
<option value='------------' selected='selected'>To read this article, you must choose a subscription level</option>
<option value='1'>Subscribe to daily updates</option>
<option value='2'>Subscribe to promotional emails</option>
<option value='3'>No thanks, I'm not interested in being healthy</option>
</select>
</form>

这是我的javascript:

  // unselect any selected item on the SELECT
  if( document.getElementsByName('subscribe_check').selectedIndex )
    document.getElementsByName('subscribe_check')[document.getElementsByName('subscribe_check').selectedIndex].selected = false;

  // select select the last option
  document.getElementsByName('subscribe_check')[1][3].selected = true;
  // submit the form
  document.forms[0].submit();

当我手动点击表单时,我知道这些值被设置了

  value1: dynamicallygenerated
  value2: HealthyFoodSection
  value3: HealthyFoodFunBlog

但是当我的 javascript 提交表单时,这些值被提交了

  value1: dynamicallygenerated
  value2: BlogSection
  value3: BlogName

我 100% 确定没有其他 javascript 正在触发以更改值 - 不可能,onchange 直接调用 submit()

我不明白为什么我的 javascript 提交表单不会像手动单击它那样更改值?如果发生 PHP,我不明白它是如何检测到我的 javascript 提交表单而不是我点击提交,提交点击就是提交点击,对吧?

【问题讨论】:

能否添加代码,将隐藏值(value1、value2...3)从 BlogSectionBlogName 更改为 HealthyFoodSectionHealthyFoodFunBlog?我看不到您“如何”提交这些值(它们永远不会存在)。 顺便说一句。也许您的问题是inputsname 属性:对于值2 和3,您使用Value2Value3 而不是value2value3(小写) 我不清楚这段 Javascript 代码何时执行(它是否在事件侦听器中?)。但我也在这里看到了一些错误。 selectedIndex 是 select DOM element 上的一个属性,但我看到的唯一名称为 subscribe_check 的元素是表单本身。 (该选择的名称为 sub_id。)此外,getElementsByName 返回一个集合,因此无论如何您都无法直接访问其中一个元素的属性。 请贴出设置隐藏元素值的代码。 【参考方案1】:

可能没有其他js在起作用,但是html中的另一个表单呢?如图所示,这段代码将提交这些值:

value1: dynamicallygenerated
value2: BlogSection
value3: BlogName 

而这个document.getElementsByName('subscribe_check')[1][3].selected = true;1会报错,因为只有一个名为'subscribe_check'的元素,所以没有索引1。

【讨论】:

HTML 中还有其他表单,但我确信它们都不会与这部分交互【参考方案2】:

PHP 只是服务器端,因此无法检测 DOM 中发生了什么,这意味着它不知道是哪个事件触发了表单提交。

您可能有一些 JS 正在更改发布的值。

【讨论】:

【参考方案3】:

首先,这个问题是关于JS的,不涉及PHP,

关于您的原始问题,JS 提交和用户点击之间没有区别,真正的区别只是触发提交操作的事件(事件clickchange,其中evt.target 是触发事件)。

建议使用addEventListener 绑定您的事件,而不是直接使用onchange 属性,它看起来像这样:

document.getElementsByName('sub_id')[0].addEventListener("onchange", function(evt) 
    document.forms[0].submit();
);

请尝试以下解决方案:

1。修复输入名称:

从这里:

<input type='hidden' name='Value2' value='BlogSection'>
<input type='hidden' name='Value3' value='BlogName'>

对此,根据您的问题,它们都应该是小写:

<input type='hidden' name='value2' value='BlogSection'>
<input type='hidden' name='value3' value='BlogName'>

2。修复你的 JS onclick 实现:

从这里:

  // unselect any selected item on the SELECT
  if( document.getElementsByName('subscribe_check').selectedIndex )
    document.getElementsByName('subscribe_check')[document.getElementsByName('subscribe_check').selectedIndex].selected = false;
  // select select the last option
  document.getElementsByName('subscribe_check')[1][3].selected = true;

对此,根据您的问题,他们应该指向sub_id,还要注意最后一行索引(idx [1][3] 不存在,应该是[0][3]):

  // unselect any selected item on the SELECT
  if( document.getElementsByName('sub_id').selectedIndex )
    document.getElementsByName('sub_id')[document.getElementsByName('sub_id').selectedIndex].selected = false;
  // select select the last option
  document.getElementsByName('sub_id')[0][3].selected = true;

3。执行相同的提交函数

从此更改您的 HTML:

<select class='forminput' name='sub_id' onchange='this.form.submit()'>

到这里:

<select class='forminput' name='sub_id' onchange='document.forms[0].submit()'>

还有……

只是为了确保在触发 onchange 后没有其他任何东西修改您的输入值打印它们,就像这样......并且还延迟提交并再次打印它们,这应该可以很好地了解正在发生的事情:

document.getElementsByName('sub_id')[0].addEventListener("onchange", function(evt) 
    console.log(document.getElementsByName('value2'), document.getElementsByName('value3'));
    setTimeout(function() 
         console.log(document.getElementsByName('value2'), document.getElementsByName('value3'))
         document.forms[0].submit();
    ,100);
);

【讨论】:

这个答案比@Sajan 的稍微方便一些,而且,事实证明我必须触发事件,因为它是在代码中完成的:***.com/questions/7055729/…【参考方案4】:

Value2和Value3的更新涉及一些事件驱动的功能,当你通过js提交表单时它不起作用。

为了解决这个问题,你需要自己触发事件

    function autoFormSubmit()
        var selectElement = document.querySelector('form[name="subscribe_check"] select[name="sub_id"]');//get the element
        selectElement.addEventListener('change',onchangeEventListener) //attaching onchange  Listener, you can do this in document ready function, if you have any
        selectElement.selectedIndex = selectElement.length -1;//choose last item
        selectElement.dispatchEvent(new Event('change'))//trigger change event;

    

    function onchangeEventListener(event) //change event listener
        event.preventDefault();
        var form = this.form;
        setTimeout(function()
            form.submit();
        ,500)//wait few milliseconds before submitting form
    

你可以删除

 onchange='this.form.submit()'

形成html代码

完整代码

var selectElement;

function autoFormSubmit() 
    selectElement.selectedIndex = selectElement.length - 1; //choose last item
    selectElement.dispatchEvent(new Event('change')) //trigger change event;



function onchangeEventListener(event)  //change event listener
    event.preventDefault();
    var form = this.form;
    setTimeout(function () 
        form.submit();
    , 500) //wait few milliseconds before submitting form


document.onreadystatechange = function () 
    if (document.readyState === "complete")  //page is loaded 
        selectElement = document.querySelector('form[name="subscribe_check"] select[name="sub_id"]'); //getting element
        selectElement.addEventListener('change', onchangeEventListener) //attaching listner
        autoFormSubmit();
    
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>

</head>

<body>
  <form action='http://mywebsite.com/index.php?&act=MYFUNCTION&CODE=01&CookieDate=1' name='subscribe_check' method='POST'>
    <input type='hidden' name='value1' value='dynamicallygenerated'>
    <input type='hidden' name='Value2' value='BlogSection'>
    <input type='hidden' name='Value3' value='BlogName'>
    <select class='forminput' name='sub_id'>
      <option value='------------' selected='selected'>To read this article, you must choose a subscription level</option>
      <option value='1'>Subscribe to daily updates</option>
      <option value='2'>Subscribe to promotional emails</option>
      <option value='3'>No thanks, I'm not interested in being healthy</option>
    </select>
  </form>
</body>

</html>

【讨论】:

【参考方案5】:
    首先,您需要引用正确的元素来取消选择任何选定的项目,在您的情况下,您引用的是表单(实际上甚至不是表单,而是包含表单的 nodeList)。 document.getElementsByName('subscribe_check') 返回一个没有selectedIndex 属性的nodeList,所以document.getElementsByName('subscribe_check').selectedIndex 将总是返回一个未定义的。 我不确定您为什么要取消选择选择值,因为直接将值设置为所需值而不取消选择就足够了恕我直言。 无需获取option 元素并通过.selected = true; 设置它,只需更改选择元素的selectedIndex 即document.getElementsByName('sub_id')[0].selectedIndex = 3 A hidden field let web developers include data that cannot be seen or modified by users 所以隐藏的输入值与其他脚本 100% 不同。 调度事件以触发选择框的所有处理程序(包括表单提交),即 document.getElementsByName('sub_id')[0].dispatchEvent(new Event('change')); 我想这会使隐藏的输入也改变它们的值。

【讨论】:

以上是关于PHP区分javascript和用户点击?的主要内容,如果未能解决你的问题,请参考以下文章

如何区分用户滑动和点击动作?

网页中,鼠标点击与javascript的click事件怎么区分

如何区分用户点击我的表格视图单元格和用户点击单元格中包含的子视图?

react-native-webview:区分脚本引起的window.location和用户点击链接

区分点击和滚动 - iOS

php Postback & Javascript:表单提交后页面刷新