防止更改HTML只读文本字段

问题描述 投票:0回答:2

我正在开发Grails Web应用程序,该应用程序的模块主要必须实现主从接口。作为一种方法,我想考虑以下代码:

大师班:

import org.codehaus.groovy.grails.web.json.JSONArray

class MyForm {
    String name
    String address
    String detail
    BigDecimal total

    static hasMany = [details: MyFormDetail]

    static constraints = {
        name()
        address()
        detail()
        total()
    }

    static mapping = {
        detail type: 'text'
    }

    def beforeInsert = {
        def detailJSON = new JSONArray(detail)
        detailJSON.each {
            def quantity = it.getAt("quantity").toString().toBigDecimal()
            def description = it.getAt("description").toString()
            def unitaryPrice = it.getAt("unitaryPrice").toString().toBigDecimal()
            def subtotal = it.getAt("subtotal").toString().toBigDecimal()
            def myFormDetail = new MyFormDetail(
                    quantity: quantity,
                    description: description,
                    unitaryPrice: unitaryPrice,
                    subtotal: subtotal
            )
            this.addToDetails(myFormDetail)
        }
    }
}

详细类别:

class MyFormDetail {
    Integer quantity
    String description
    BigDecimal unitaryPrice
    BigDecimal subtotal

    static belongsTo = [myForm: MyForm]

    static constraints = {
        quantity()
        description()
        unitaryPrice()
        subtotal()
    }
}

myFormUtilities.js帮助文件:

$(document).ready(function() {
    $("#detailTable").jqGrid({
        datatype: "local",
        height: 100,
        colNames: ["QUANTITY","DESCRIPTION","UNIT. PRICE","SUBTOTAL"],
        colModel:[ 
            {name:'quantity',index:'quantity', width:100},
            {name:'description',index:'description', width:400},
            {name:'unitaryPrice',index:'unitaryPrice', width:100},
            {name:'subtotal',index:'subtotal', width:100}],
        caption: "DETAIL"
    });

    createTable();

    $("#addRow").bind("click",addRow);
    $("#removeRow").bind("click",removeRow);

    $("#quantity, #unitaryPrice").bind("keyup",calculateTotal);

    function calculateTotal(){
        let quantity = parseFloat($("#quantity").val());
        let unitaryPrice = parseFloat($("#unitaryPrice").val());
        let subtotal = quantity*unitaryPrice;
        $("#subtotal").val(subtotal);
    }

    function addRow(){
        let row = new Object();
        row.quantity = $("#quantity").val();
        row.description = $("#description").val();
        row.unitaryPrice = $("#unitaryPrice").val();
        row.subtotal = $("#subtotal").val();
        let detailJSON = ($("#detail").val()=="")?"[]":$("#detail").val();
        let mydata = $.parseJSON(detailJSON);
        mydata.push(row);
        $("#detail").val(JSON.stringify(mydata));
        createTable();
    }

    function removeRow(){
        let filaId = parseInt($('#detailTable').jqGrid('getGridParam','selrow')) - 1;
        let mydata = $.parseJSON($("#detail").val());
        let nuevoMydata = new Array();
        for(let i=0;i<mydata.length;i++){
            if(filaId!=i)
                nuevoMydata.push(mydata[i]);
        }
        $("#detail").val(JSON.stringify(nuevoMydata));
        createTable();
    }

    function createTable(){
        let total = 0;
        let aRow = new Object();
        let detailJSON = ($("#detail").val()=="")?"[]":$("#detail").val();
        let mydata = $.parseJSON(detailJSON);
        $("#detailTable").jqGrid("clearGridData", true);
        for(let i=0;i<mydata.length;i++){
            aRow = mydata[i];
            total += parseFloat(aRow.subtotal);
            $("#detailTable").jqGrid('addRowData',i+1,aRow);
        }
        $("#total").val(total);
    }
});

这是显示的表单(我知道这是一个自动生成的视图,但是请看成一个非常基本的GUI样机):master-detail mockup

所以,这些是问题:

  • SubtotalTotal字段都是已设置的计算字段read-only阻止用户修改其内容,但我发现使用浏览器元素检查器的内容和属性(如只读)可以修改。

  • detail同样发生。如果其内容被更改,则在服务器端保存实例时将产生错误,因为beforeInsert块需要有效用于创建detail实例的JSON字符串。此字段还用于生成详细信息JqGrid。该字段将是隐藏。

此示例的所有操作均按预期工作,但好奇的用户可能会导致故障。

  • 是否有一种方法可以防止这些字段的文本被更改,即使使用检查员?
  • 还有另一个place,以确保此数据不受更改的影响吗?
  • 我正在使用此detail字段来保存JSON字符串,这是实现主从模式的解决方案。还有另一个改进此实现方式的方法,无需定义此字符串的字段?
javascript html grails jqgrid master-detail
2个回答
0
投票

如果您的用户有权访问检查器/ Web控制台,则他们有权访问您执行的所有客户端数据(它们仅受其如何使用浏览器开发工具的知识所限制)。他们可以更改任何元素的文本或输入的值。因此,唯一可以100%安全地存储此数据的位置是在服务器端。

[您可以尝试做的是,至少隐藏每个输入(例如,使用CSS)并将其替换为可见,这至少会使他们更新任何东西,并可能阻止更改事件调用服务器,具有<span>元素(或其他一些非格式元素)的HTML。然后确保无论何时更改<input>值,都将更新相应跨度的文本。类似于:

$("#subtotalSpan").html( $("#subtotal").val() );

添加在calculateTotal函数内部。如果您希望他们甚至无法编辑跨度的HTML,则可以走得更远,并将值绘制到<canvas>而不是<span>。他们将无法更改绘制到canvas元素中的文本。


0
投票

[抱歉,对于保护从浏览器发送的数据没有简单的答案。您的服务器应将任何用户提交的输入视为脏内容。

在POST或GET中发送的数据始终可以在客户端更改,甚至可以批量创建(使用CURL或Postman之类的东西)。因此,您应该始终在服务器端验证用户输入并在此计算您的总数。

© www.soinside.com 2019 - 2024. All rights reserved.