You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Javascript与JSON缓存异常:Import后Refresh数据未正确提交

功能说明

  • PHP模块读取CSV文件并将其数据转换为数组
  • 通过HTML与PHP循环构建表格,展示CSV数据
  • 表格的每一行均包含「Import Risk」按钮和「Refresh」按钮
  • 点击「Import Risk」按钮会触发AJAX请求至ajax-import.php,发送该行关联的JSON数据
  • 解析ajax-import.php的响应,若成功则更新表格行的风险信息或错误提示
  • 每行的JSON数据存储在「Import Risk」按钮的data-json属性中
  • 点击「Refresh」按钮会触发AJAX请求至refresh.php,获取该行的最新数据并更新表格行

问题描述

点击「Import Risk」按钮后,再点击「Refresh」按钮时,data-json属性已被刷新,但再次点击「Import Risk」按钮时,发送至ajax-import.php的JSON仍是首次点击Import时的初始版本。

诉求

实现点击「Refresh」按钮时可随时刷新data-json,且更新后的JSON能被正确发送至ajax-import.php进行处理。

代码实现

<!-- Start Table Content -->
<div class="row">
    <div class="col-12">
        <div class="card">
            <div class="card-body">
                <h2>CSV File Contents</h2>

                <?php $csvtoarray_clean = sanitize_csv_file($file_path); ?>

                <?php  // Convert the CSV data to an array
                $csvtoarray = array_map('str_getcsv', explode("\n", $csvtoarray_clean));
                ?>

                <div class="table-responsive">
                    <table class="table table-bordered">
                        <thead>
                            <tr>
                                <th>#</th>
                                <?php foreach($csvtoarray[0] as $col): ?>
                                    <th><?= htmlspecialchars($col) ?></th>
                                <?php endforeach; ?>
                                <th>JSON Output</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php for($i=1; $i<count($csvtoarray); $i++): ?>

                                <tr>
                                    <td><?= $i; ?></td>
                                    <?php foreach($csvtoarray[$i] as $cell): ?>
                                        <td><?= htmlspecialchars($cell) ?></td>
                                    <?php endforeach; ?>

                                    <?php $json_data = processJson(json_encode(array_combine($csvtoarray[0], $csvtoarray[$i])),$file_ref); ?>
                                    <td style="min-width: 550px;">
                                        <code>    
                                            <?php echo removeEmptyValues($json_data);?>
                                            <?php $validation_response = json_decode($json_data, true); ?>
                                        </code>
                                    </td>
                                    
                                    <td class="response-col">
                                        <?php if ($validation_response['status'] == 'error'): ?>
                                            <strong>There are errors on this row of data:</strong>
                                            <?php foreach ($validation_response['errors'] as $error): ?>
                                                <li><?= htmlspecialchars($error) ?></li>
                                                <button class="refresh-btn btn btn-secondary" data-row="<?= $i ?>" data-hash="<?= md5(serialize($csvtoarray[$i])) ?>">Refresh</button>
                                            <?php endforeach; ?>
                                        <?php else: ?>
                                            <div class="alert alert-danger" role="alert" style="display: none;"></div>
                                            <div class="btn-group" role="group" aria-label="Actions">
                                                <button class="import-button btn btn-primary" data-row="<?= $i ?>" data-json="<?php echo htmlspecialchars(removeEmptyValues($json_data)) ?>">Import Risk</button>
                                                <button class="refresh-btn btn btn-secondary" data-row="<?= $i ?>" data-hash="<?= md5(serialize($csvtoarray[$i])) ?>">Refresh</button>
                                            </div>
                                        <?php endif; ?>
                                    </td>
                                </tr>
                            <?php endfor; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>                
    </div>
</div>
<!-- End Table Contents -->

<script>
    $(document).ready(function() {
        // Handle import button click
        $(document).on('click', '.import-button', function() {
            var json_data = $(this).data('json');

            var button = $(this);
            var alert = button.closest('tr').find('.alert');
            alert.hide();

            $.ajax({
            type: 'POST',
            url: 'ajax-import.php?cache=' + new Date().getTime(), // Add cache-busting parameter to the URL
            data: {
                json_data: button.data('json'), // Fetch the latest data-json value from the button
                cacheBuster: new Date().getTime() // Cache-busting parameter
            },
            beforeSend: function(xhr) {
                xhr.setRequestHeader('Cache-Control', 'no-cache');
            },
            success: function(response) {
                try {
                var data = JSON.parse(response);

                var risk_number = data.result.riskNumber;
                var risk_url = data.result.riskURL;
                var status = data.result.status;
                var responseText = data.result.responseText;
                var errorText = data.result.errorText;

                if (risk_url !== undefined) {
                    button.closest('tr').find('.response-col').html('<a href="' + risk_url + '" class="btn btn-primary" target="_blank">' + risk_number + '</a>');
                } else {
                    var alertContent = '<h4 class="alert-heading">' + responseText + '</h4>' + errorText;
                    alert.html(alertContent);
                    alert.show();
                }

                // Log the data being sent to the import script
                console.log('Import Data:', button.data('json')); // Log the latest data-json value

                // Refresh the data in the table row
                updateDataAndDOM(button, response);
                } catch (error) {
                console.error('Error parsing JSON:', error);
                }
            },
            error: function(xhr, status, error) {
                var errorMessage = 'Error: ' + error;
                alert.html(errorMessage);
                alert.show();

                button.text('Failed');
                button.addClass('btn-danger');
            }
            });
        });

        // Function to update JSON data and DOM elements
        function updateDataAndDOM(refreshButton, refreshedData) {
            var row = refreshButton.data('row');

            var refreshedRowData = JSON.parse(refreshedData);
            var rowDataElements = refreshButton.closest('tr').find('td:not(.response-col)');
            rowDataElements.each(function(index) {
            var header = $(this).closest('table').find('th').eq(index).text();
            var newData = refreshedRowData[header];
            if (newData !== undefined) {
                $(this).text(newData);
            }
            });

            importButton = refreshButton.closest('tr').find('.import-button[data-row="' + row + '"]');
            importButton.attr('data-json', refreshedData); // Update the data-json attribute
        }

        // Handle refresh button click
        $(document).on('click', '.refresh-btn', function() {
            var refreshButton = $(this);
            var row = refreshButton.data('row');
            var hash = refreshButton.data('hash');

            $.ajax({
            url: 'refresh.php',
            data: {
                row: row,
                hash: hash,
                csvFilePath: '<?php echo $file_path; ?>',
                timestamp: new Date().getTime() // Append timestamp as a parameter
            },
            type: 'GET',
            dataType: 'json',
            success: function(response) {
                if (response.status === 'refreshed') {
                var refreshedData_raw = response.refreshed_data;
                var refreshedData = JSON.stringify(refreshedData_raw);
                console.log('Refreshed Data:', refreshedData_raw);

                updateDataAndDOM(refreshButton, refreshedData);
                } else {
                console.log(response.message);

                var emptyData = '{}';
                updateDataAndDOM(refreshButton, emptyData);
                }
            },
            error: function(xhr, status, error) {
                console.log('Error: ' + error);

                var emptyData = '{}';
                updateDataAndDOM(refreshButton, emptyData);
            }
            });
        });
    });
</script>

问题原因与修复方案

核心原因

jQuery的data()方法会将DOM元素的data-*属性值缓存到内存中,后续调用data('json')时优先读取缓存值,而非最新的DOM属性值。你的代码中updateDataAndDOM函数仅用attr('data-json', refreshedData)更新了DOM属性,但未同步更新jQuery的缓存,导致「Import Risk」点击时仍读取旧的缓存值。

修复步骤

方案1:同步DOM属性与jQuery缓存

修改updateDataAndDOM函数,在更新DOM属性后,同步更新jQuery的data缓存:

function updateDataAndDOM(refreshButton, refreshedData) {
    var row = refreshButton.data('row');

    var refreshedRowData = JSON.parse(refreshedData);
    var rowDataElements = refreshButton.closest('tr').find('td:not(.response-col)');
    rowDataElements.each(function(index) {
        var header = $(this).closest('table').find('th').eq(index).text();
        var newData = refreshedRowData[header];
        if (newData !== undefined) {
            $(this).text(newData);
        }
    });

    // 修正:添加var声明避免全局变量污染,同时同步缓存
    var importButton = refreshButton.closest('tr').find('.import-button[data-row="' + row + '"]');
    importButton.attr('data-json', refreshedData); // 更新DOM属性
    importButton.data('json', refreshedData); // 同步jQuery缓存
}

方案2:直接读取DOM属性(跳过缓存)

如果不想维护缓存,可在「Import Risk」的点击事件中直接读取DOM的data-json属性值,而非依赖jQuery的data()缓存:

$(document).on('click', '.import-button', function() {
    var button = $(this);
    // 修正:直接读取DOM属性,跳过jQuery缓存
    var json_data = button.attr('data-json');
    var alert = button.closest('tr').find('.alert');
    alert.hide();

    $.ajax({
        type: 'POST',
        url: 'ajax-import.php?cache=' + new Date().getTime(),
        data: {
            json_data: json_data, // 使用直接读取的最新值
            cacheBuster: new Date().getTime()
        },
        // 后续代码保持不变
    });
});

额外优化提示

  • 原代码中importButton变量未用var/let/const声明,会造成全局变量污染,建议添加var或const约束作用域。
  • 成功导入后替换response-col内容时,会移除「Import Risk」和「Refresh」按钮,若后续仍需对该行进行操作,需保留按钮或重新渲染操作区域。

内容的提问来源于stack exchange,提问作者Claud

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 22:37:01