我正在嘗試為網站建立一個管理面板(CRUD 操作)。我首先建立 API 端點,然後將其託管在我的子網域上。我現在正在從該端點獲取數據。顯示所有聯絡人 (GET)、單一聯絡人 (GET) 和新增聯絡人 (POST) 效果很好,但我在更新聯絡人 (PUT) 方面卡住了好幾天。
預填表格運作正常。當我提交資料時,出現以下錯誤:
Access to XMLHttpRequest at 'https://api.itisgoodtohave.me/contacts/update.php' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status. PUT https://api.itisgoodtohave.me/contacts/update.php net::ERR_FAILED Uncaught (in promise) AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
update.php
:
<?php header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Headers: *"); header("Access-Control-Allow-Methods: *"); include 'DbConnection.php'; $objDb = new DbConnection; $conn = $objDb->connect(); $method = $_SERVER['REQUEST_METHOD']; if ($method = "POST") { $contact = json_decode(file_get_contents('php://input')); $sql = "UPDATE contacts SET name=:name, email=:email, phone=:phone WHERE id=:id"; $stmt = $conn->prepare($sql); $stmt->bindParam(':id', $contact->id); $stmt->bindParam(':name', $contact->name); $stmt->bindParam(':email', $contact->email); $stmt->bindParam(':phone', $contact->phone); if ($stmt->execute()) { $response = ['status' => 1, 'message' => "Contact updated sucessfully."]; } else { $response = ['status' => 0, 'message' => "Could not update contact."]; } echo json_encode($response); } else { echo "some error occured"; }
EditContact.js
import React from 'react'; import axios from 'axios'; import { useState, useEffect } from 'react'; import { useNavigate, useParams } from 'react-router-dom'; export default function EditContact() { const [inputs, setInputs] = useState([]) const navigate = useNavigate(); const { id } = useParams(); useEffect(() => { showContact(); }, []) function showContact() { axios.get(`https://api.mywebsite.com/contacts/single_read.php/?id=${id}`) .then(function(response) { setInputs(response.data); }) } const handleChange = (event) => { const name = event.target.name; const value = event.target.value; setInputs(values=> ({...values, [name]: value})); console.log(inputs) } const handleSubmit = (event) => { event.preventDefault(); axios.put('https://api.mywebsite.com/contacts/update.php', inputs) .then(function(response){ console.log(response) navigate('/admin/contacts') }) } return ( <div> <h3>Edit Contact</h3> <form onSubmit={handleSubmit}> <label>Name</label> <input defaultValue={inputs.name} type="text" name="name" onChange={handleChange} /> <br /> <label>Email</label> <input defaultValue={inputs.email} type="text" name="email" onChange={handleChange} /> <br /> <label>Phone</label> <input defaultValue={inputs.phone} type="text" name="phone" onChange={handleChange} /> <br /> <button type="submit">Save</button> </form> </div> ) }
我已經嘗試了郵差中的每個端點。所有這些(GET、POST、PUT、DELETE)都在工作。這些條目已在我的資料庫中更新。
經過幾個小時的 CORS 谷歌搜尋、再次重寫我的程式碼等之後,我就是無法理解。我對編碼還很陌生,但對我來說,POST 有效但 PUT 無效似乎不合邏輯(或者我在這裡缺少一些基本邏輯)。
如果有人能提出新想法,我會很高興。我渴望學習:)
Postman 是 HTTP 用戶端,而不是瀏覽器。 CORS 適用於瀏覽器,因此 HTTP 用戶端將忽略這些標頭。因此,使用 Postman 呼叫 API 時不會出現任何問題,這是完全合理的。
錯誤訊息的重要部分是
對預檢請求的回應未通過存取控制檢查:它沒有 HTTP 正常狀態
。 預檢請求是帶有 OPTIONS 方法的 HTTP 請求。您可以將此視為偵察請求,以檢查是否允許發出進一步的請求 (請參閱 MDN 文件)。此錯誤表示此 OPTIONS 請求的回應不是 HTTP 200。此處的解決方案是確保 OPTIONS 請求將導致設定了所有 CORS 標頭的 HTTP 200。