reactjs NextJS:CORS策略阻止从源访问XMLHttpRequest:请求的资源上不存在“Access-Control-Allow-Origin”标头

vuktfyat  于 2023-01-25  发布在  React
关注(0)|答案(1)|浏览(214)

我正在使用NextJS作为前端,Solidity作为后端开发NFT Marketplace应用程序。当我尝试使用前端UI销售NFT时,我遇到了这个错误:
Access to XMLHttpRequest at 'https://gateway.pinata.cloud/ipfs/QmbbWLfoPg9aSpFCKoYQRadQynmCRMjydVhkXJZKBXKnyT' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
下面是我的代码:

import {useState} from 'react';
import {ethers} from 'ethers';
import {useRouter} from 'next/router';
import Web3Modal from 'web3modal';
import {contractAddress, INFURA_URL, PINATA_KEY, PINATA_SECRET} from '../config.js';
import NFTMarketplace from "../abi/NFTMarketplace.json";
import axios from 'axios';
import Image from 'next/image';

export default function createNFT() {
    const [fileURL, setFileURL] = useState(null);
    const [formInput, updateFormInput] = useState({price: "", name: "", description: ""});
    const router = useRouter();
    const [loadingState, setLoadingState] = useState('Not loaded');

    // upload image to IPFS
    async function imageUpload(e) {
        const file = e.target.files[0];
        try {
            const formData = new FormData();
            formData.append("file", file);
            const resFile = await axios({
                method: "post",
                url: "https://api.pinata.cloud/pinning/pinFileToIPFS",
                data: formData,
                headers: {
                    'pinata_api_key': PINATA_KEY,
                    'pinata_secret_api_key': PINATA_SECRET,
                    'Content-Type': 'multipart/form-data'
                }
            });

            const imageURL = `https://gateway.pinata.cloud/ipfs/${
                resFile.data.IpfsHash
            }`;
            setFileURL(imageURL)

        } catch (e) {
            console.log(e)
        }
    }

    // upload metadata to IPFS and return URL to use in later transaction
    async function uploadToIPFS() {
        const {name, description, price} = formInput;
        if (!name || !description || !price || !fileURL) {
            return
        }
        setLoadingState('Loading...')

        try {
            let jsonData = JSON.stringify({
                "pinataMetadata": {
                    "name": `${
                        name.json
                    }`
                },
                "pinataContent": {
                    name,
                    description,
                    image: fileURL
                }
            })

            const resFile = await axios({
                method: "post",
                url: "https://api.pinata.cloud/pinning/pinJSONToIPFS",
                data: jsonData,
                headers: {
                    'pinata_api_key': PINATA_KEY,
                    'pinata_secret_api_key': PINATA_SECRET,
                    'Content-Type': 'application/json'
                }
            });

            const tokenURI = `https://gateway.pinata.cloud/ipfs/${
                resFile.data.IpfsHash
            }`;
            return tokenURI;
        } catch (error) {
            console.log("Error uploading file: ", error);
        }
    }

    async function listNFTForSale() {
        const tokenURI = await uploadToIPFS();
        const web3modal = new Web3Modal();
        const connection = await web3modal.connect();
        const provider = new ethers.providers.Web3Provider(connection);
        const getnetwork = await provider.getNetwork();
        const goerliChainId = 5;
        if (getnetwork.chainId != goerliChainId) {
            alert("You are not connected to the Goerli network!")
            return;
        }
        // sign the transaction
        const signer = provider.getSigner();
        const contract = new ethers.Contract(contractAddress, NFTMarketplace.abi, signer);
        const price = ethers.utils.parseUnits(formInput.price, 'ether');
        let listingPrice = await contract.getListingPrice();
        listingPrice = listingPrice.toString();
        let transaction = await contract.createToken(tokenURI, price, {value: listingPrice});
        await transaction.wait();
        router.push('/');
    }
    return (<div className='flex justify-center'>
        <div className='w-1/8 flex-col mr-10 mt-10'> {
            !fileURL && (<Image className='rounded mt-4' src='/image_place_holder.jpg' alt="Image placeholder" width={300} height={200}/>)
        }
            {
            fileURL && (<Image src={fileURL} alt="Image uploaded successfully" className='rounded mt-4' placeholder="blur" blurDataURL="/image_place_holder.jpg" width={300} height={200}/>)
        }</div>
        <div className='w-1/2 flex flex-col'>
            <input placeholder='Asset Name' className='mt-8 border rounded p-4' onChange={e=>updateFormInput({...formInput, name: e.target.value})}/>
            <textarea placeholder='Asset Description' className='mt-2 border rounded p-4' onChange={e=>updateFormInput({...formInput, description: e.target.value})}/>
            <input placeholder='Asset Price in Ethers' className='mt-2 border rounded p-4' type="number" onChange={e=>updateFormInput({...formInput, price: e.target.value})}/>
            <input type="file" name="Asset" className='my-4' onChange={imageUpload} /> {
            fileURL && (<button onClick={listNFTForSale} className="font-bold mt-4 bg-pink-500 text-white rounded p-4 shadow-lg"> {
                loadingState == 'Not loaded' ? 'Create NFT' : 'Uploading...'
            } </button>)
        } </div>
    </div>)
}

我没有足够的声誉,所以我只能提供图片的链接。
Unhandled Runtime Error on UI
NFT Sell Page UI
未处理的运行时错误中出现的错误是:

Unhandled Runtime Error
AxiosError: Network Error

Call Stack
XMLHttpRequest.handleError
node_modules/axios/lib/adapters/xhr.js (154:0)

我尝试在Chrome上安装Access-Control-Allow-Origin扩展,但它不起作用。其他建议的方法通常适用于ExpressJS和NodeJS,但我使用的是NextJS。我该如何解决这个问题?

hgncfbus

hgncfbus1#

我也遇到过同样的问题,在axios请求头中添加以下内容解决了我的问题。我不确定您收到错误的请求,但您可以在控制台中展开错误,它应该告诉生成错误的文件/行。
'Accept': 'text/plain'
例如:

const resFile = await axios({
            method: "post",
            url: "https://api.pinata.cloud/pinning/pinFileToIPFS",
            data: formData,
            headers: {
                'Accept': 'text/plain',
                'pinata_api_key': PINATA_KEY,
                'pinata_secret_api_key': PINATA_SECRET,
                'Content-Type': 'multipart/form-data'
            }
        });

更多关于:https://knowledge.pinata.cloud/en/articles/6848516-how-to-fix-400-errors-with-dedicated-gateways
以及
https://stackoverflow.com/a/35553666/18100033
希望能有所帮助。

相关问题