【问题标题】:Php differentiating between javascript and user click?PHP区分javascript和用户点击?
【发布时间】: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 代码何时执行(它是否在事件侦听器中?)。但我也在这里看到了一些错误。 selectedIndexselect DOM element 上的一个属性,但我看到的唯一名称为 subscribe_check 的元素是表单本身。 (该选择的名称为 sub_id。)此外,getElementsByName 返回一个集合,因此无论如何您都无法直接访问其中一个元素的属性。
  • 请贴出设置隐藏元素值的代码。

标签: javascript forms post


【解决方案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);
    });
    

    【讨论】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-29
        • 2023-04-02
        相关资源
        最近更新 更多