首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 無表單提交數據實現:JavaScript 動態構造 URL 參數實現增刪改查

     編輯:PHP 相關知識

場景說明

傳統 `

` 提交會導致頁面跳轉。本範例展示如何在不使用 `` 標籤的情況下,透過 JavaScript 讀取 `` 值,拼接 URL 參數,以 `location.href` 跳轉至處理腳本(`public.php`),實現城市分類的「編輯、刪除、新增」操作。

頁面結構與邏輯

1. PHP 端:查詢子城市列表

<?php
include("../inc/inc.php");
islogin();
$Db = new Db(); // 自定義資料庫類

$id = (int)($_GET['aid'] ?? 0);
if (!$id) exit;

$query = $Db->query("SELECT upid, cntitle, orderid, id FROM cn_loupan_city WHERE upid = $id ORDER BY orderid ASC");
$rows = $Db->fetch($query); // 返回二維陣列
?>

2. HTML 表格:每行獨立輸入框 + 操作連結

<table class="table_list">
  <caption>{<?=htmlspecialchars($_GET['cname'])?>} 地區管理</caption>
  <tr>
    <th width="32%">地區名稱</th>
    <th width="43%">排序位置</th>
    <th width="25%">操作</th>
  </tr>
  <?php foreach ($rows as $v): ?>
  <tr>
    <td class="align_c">
      <input id="c_<?=$v[3]?>" type="text" size="30" value="<?=htmlspecialchars($v[1])?>" />
    </td>
    <td class="align_c">
      <input id="s_<?=$v[3]?>" type="text" size="20" value="<?=htmlspecialchars($v[2])?>" />
    </td>
    <td class="align_c">
      <a href="javascript:sava('c_<?=$v[3]?>','s_<?=$v[3]?>',<?=$v[3]?>);">保存</a> |
      <a href="javascript:del(<?=$v[3]?>);">刪除</a>
    </td>
  </tr>
  <?php endforeach; ?>
</table>

3. JavaScript:驗證 → 拼接 URL → 跳轉

<script>
function del(id) {
    if (confirm('確認刪除此條信息?')) {
        location.href = `public.php?action=deletes&id=${id}&aid=${}&cname=${encodeURIComponent('')}`;
    }
}

function sava(titleId, orderId, id) {
    if (!confirm('確認你輸入數據無誤?')) return;

    const cntitle = document.getElementById(titleId).value.trim();
    const orderid = document.getElementById(orderId).value.trim();

    if (!cntitle || cntitle.length > 30) {
        alert('地區名稱不能為空且不超過 30 字元!'); return;
    }
    if (isNaN(orderid)) {
        alert('排序位置請輸入數字!'); return;
    }

    location.href = `public.php?action=edits&title=${encodeURIComponent(cntitle)}&orderid=${orderid}&id=${id}&aid=${}&cname=${encodeURIComponent('')}`;
}
</script>

安全性與架構缺陷分析

問題風險修正方案
直接將 PHP 變數輸出至 JS 字串XSS 注入(若 cname 含單引號/腳本)使用 json_encode() 輸出 JS 變數,或 data-* 屬性
SQL 拼接變數 $id 未預處理SQL 注入PDO 預處理語句
操作使用 GET 請求(刪除/修改)CSRF、瀏覽器預取觸發誤刪、不符合 REST改為 POST/DELETE,配合 CSRF Token
無伺服器端驗證權限越權操作後端驗證用戶是否擁有該城市管理權限
JS 驗證可繞過非法資料入庫後端必須重複驗證

現代化重構:AJAX + RESTful API + Vue 3 元件

後端 API 路由設計

GET    /api/cities?parent_id=1        # 列表
POST   /api/cities                    # 新增
PUT    /api/cities/{id}               # 更新
DELETE /api/cities/{id}               # 刪除

Vue 3 元件實現

<script setup>
import { ref, onMounted } from 'vue';

const props = defineProps(['parentId', 'parentName']);
const cities = ref([]);
const loading = ref(false);

async function load() {
    const res = await fetch(`/api/cities?parent_id=${props.parentId}`);
    const {data} = await res.json();
    cities.value = data;
}
onMounted(load);

async function save(city) {
    city.editing = false;
    const res = await fetch(`/api/cities/${city.id}`, {
        method: 'PUT',
        headers: {'Content-Type':'application/json', 'X-CSRF-TOKEN': csrfToken},
        body: JSON.stringify({name: city.name, order: city.order})
    });
    if (!res.ok) { city.editing = true; alert('保存失敗'); }
}

async function remove(id) {
    if (!confirm('確認刪除?')) return;
    await fetch(`/api/cities/${id}`, {method:'DELETE', headers:{'X-CSRF-TOKEN': csrfToken}});
    cities.value = cities.value.filter(c => c.id !== id);
}
</script>

<template>
  <div class="card">
    <h4>{{ parentName }} 地區管理</h4>
    <table>
      <thead><tr><th>名稱</th><th>排序</th><th>操作</th></tr></thead>
      <tbody>
        <tr v-for="city in cities" :key="city.id">
          <td>
            <input v-if="city.editing" v-model="city.name" @blur="save(city)" @keyup.enter="save(city)" />
            <span v-else @dblclick="city.editing=true">{{ city.name }}</span>
          </td>
          <td>
            <input v-if="city.editing" type="number" v-model.number="city.order" @blur="save(city)" />
            <span v-else @dblclick="city.editing=true">{{ city.order }}</span>
          </td>
          <td>
            <button v-if="city.editing" @click="save(city)">保存</button>
            <button v-else @click="city.editing=true">編輯</button>
            <button @click="remove(city.id)" class="danger">刪除</button>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

總結

「無表單提交」本質上是「前端收集數據 → 發送 HTTP 請求」的另一種寫法。原始範例雖實現了基本交互,但存在 XSS、CSRF、SQL 注入、REST 不合規等嚴重問題。現代化開發應採用:

  1. 前後端分離:Vue/React + RESTful/GraphQL API
  2. 統一錯誤處理、載入狀態、樂觀鎖/防抖
  3. 後端:DTO 驗證、權限策略、資源授權、審計日誌
  4. 安全:CSP、HTTPS、CSRF Token、SameSite Cookie、輸入輸出編碼
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved