Saya cuba mencipta panel pentadbir (operasi CRUD) untuk tapak web. Saya mula-mula mencipta titik akhir API dan kemudian mengehoskannya pada subdomain saya. Saya kini mendapat data dari titik akhir itu. Menunjukkan semua kenalan (GET), kenalan individu (GET) dan menambah kenalan baharu (POST) berfungsi dengan baik, tetapi saya terperangkap selama berhari-hari mengemas kini kenalan (PUT).
Borang praisi berfungsi dengan baik. Apabila saya menyerahkan data, saya mendapat ralat berikut:
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> ) }
Saya telah mencuba setiap titik akhir dalam posmen. Kesemuanya (DAPATKAN, POS, LETAK, PADAM) berfungsi. Entri ini telah dikemas kini dalam pangkalan data saya.
Selepas berjam-jam googling tentang CORS, menulis semula kod saya sekali lagi, dsb., saya tidak dapat memahaminya. Saya agak baru dalam pengekodan, tetapi nampaknya tidak logik kepada saya bahawa POST berfungsi tetapi PUT tidak (atau saya kehilangan beberapa logik asas di sini).
Saya akan gembira jika ada yang boleh mencadangkan idea baru. Saya bersemangat untuk belajar :)
Postman ialah klien HTTP, bukan pelayar. CORS berfungsi dalam penyemak imbas, jadi pelanggan HTTP akan mengabaikan pengepala ini. Jadi masuk akal bahawa anda tidak akan menghadapi sebarang masalah memanggil API menggunakan Posman.
Bahagian penting mesej ralat ialah
对预检请求的响应未通过访问控制检查:它没有 HTTP 正常状态
. Permintaan preflight ialah permintaan HTTP dengan kaedah OPTIONS. Anda boleh menganggap ini sebagai permintaan recon untuk menyemak sama ada permintaan lanjut dibenarkan (Lihat dokumentasi MDN). Ralat ini menunjukkan bahawa respons kepada permintaan OPTIONS ini bukan HTTP 200. Penyelesaian di sini adalah untuk memastikan bahawa permintaan OPTIONS akan menghasilkan HTTP 200 dengan semua pengepala CORS ditetapkan.