我正在使用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。我该如何解决这个问题?
1条答案
按热度按时间hgncfbus1#
我也遇到过同样的问题,在axios请求头中添加以下内容解决了我的问题。我不确定您收到错误的请求,但您可以在控制台中展开错误,它应该告诉生成错误的文件/行。
'Accept': 'text/plain'
例如:
更多关于:https://knowledge.pinata.cloud/en/articles/6848516-how-to-fix-400-errors-with-dedicated-gateways
以及
https://stackoverflow.com/a/35553666/18100033
希望能有所帮助。