У меня проблема с запросом XMLHttpRequest. У меня есть простой интерфейс загрузки файла и передачи его на сервер для создания умных контрактов. Если я делаю один запрос, он работает нормально, но когда я пытаюсь загрузить файл с более чем 200 строками, я использую не кнопку отправки в форме, а созданную мной функцию, и получаю ошибку CORS:
Доступ к XMLHttpRequest в 'http://localhost/deploy_client' от источника 'http://localhost: 8080 ' был заблокирован политикой CORS: Ответ на запрос предполетной проверки не прошел проверка контроля доступа: в запрашиваемом ресурсе отсутствует заголовок «Access-Control-Allow-Origin».
Я использую JavaScript и Node.JS с библиотекой Express. Я запускаю сервер на порту 80, а интерфейс на 8080.
Код для интерфейса:
<form id="myForm" action="http://localhost:80/deploy_client" method="POST">
Platform address: <input type="text" name="platformAddress"><br>
Insurer Address: <input type="text" name="insurerAddress"><br>
Client UIC: <input type="text" id="clientUIC" name="clientUIC"><br>
Client Name: <input type="text" id="clientName" name="clientName"><br>
Client Group: <input type="text" id="clientGroup" name="clientGroup"><br>
NACE: <input type="text" id="clientNACE" name="clientNACE"><br>
Credit Line: <input type="text" id="clientCreditLine" name="clientCreditLine"><br>
Credit Line Date: <input type="text" id="clientCreditLineDate" name="clientCreditLineDate"><br>
Currency: <input type="text" id="clientCurrency" name="clientCurrency"><br>
City: <input type="text" id="clientCity" name="clientCity"><br>
Country: <input type="text" id="clientCountry" name="clientCountry"><br>
Import Client Data: <input id="filePath" onchange='importClientData(event)' name="filePath" type="file" accept=".csv"><br>
<button id="createClient" onclick='deployClient()'>Deploy Client</button>
</form>
<script>
function deployClient()
{
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:80/deploy_client", true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send();
}
function importClientData(event) {
var input = event.target;
console.log("File Path: " + input);
var reader = new FileReader();
reader.onloadend = function(){
var newLine=String.fromCharCode(13)+String.fromCharCode(10);
var clientLines=reader.result.split(newLine);
var numLines = clientLines.length;
console.log("clientLines[0]: " + clientLines[0]);
var myColumn;
for (var i=1;i<numLines;i++)
{
myColumn = clientLines[i].split(",");
var myClientUIC = myColumn[0];
var myClientName = myColumn[1];
var myClientGroup = myColumn[2];
var myClientCity = myColumn[5];
var myClientCountry = myColumn[7];
var myCreditLine = parseInt(myColumn[8])*1000000;
// 25569 = 1/1/1970 start of Unix time
var myCreditLineDate = (parseInt(myColumn[9])-25569)*86400;
var myCurrency = myColumn[10];
var myNACE = myColumn[11];
console.log("myClientUIC: " + myClientUIC);
console.log("myClientName: " + myClientName);
console.log("myClientGroup: " + myClientCity);
console.log("myClientCity: " + myClientCity);
console.log("myClientCountry: " + myClientCountry);
console.log("myCreditLine: " + myCreditLine);
console.log("myCreditLineDate: " + myCreditLineDate);
console.log("myCurrency: " + myCurrency);
console.log("myNACE: " + myNACE);
if (myClientUIC != "") // This avoids trying to load empty rows
{
// Call portfolio smart contract to create client
document.getElementById("clientUIC").innerHTML = myClientUIC;
document.getElementById("clientName").innerHTML = myClientName;
document.getElementById("clientGroup").innerHTML = myClientGroup;
document.getElementById("clientNACE").innerHTML = myNACE;
document.getElementById("clientCreditLine").innerHTML = myCreditLine;
document.getElementById("clientCreditLineDate").innerHTML = myCreditLineDate;
document.getElementById("clientCurrency").innerHTML = myCurrency;
document.getElementById("clientCity").innerHTML = myClientCity;
document.getElementById("clientCountry").innerHTML = myClientCountry;
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:80/deploy_client", true);
xhr.withCredentials = true;
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send({ 'request': "authentication token" });
//xhr.send();
} // if (myClientID <> "")
}
};
reader.readAsText(input.files[0]);
}; // function openInvoiceFile(event) {
</script>
Код для сервера:
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const Web3 = require("web3");
const HDWalletProvider = require("@truffle/hdwallet-provider");
require('dotenv').config();
const provider = new HDWalletProvider(process.env.MNEMONIC, process.env.INFURA_URL);
var contract = require("@truffle/contract");
const platformArtifacts = require('./build/contracts/Platform.json');
var platformContract = contract(platformArtifacts);
platformContract.setProvider(provider);
app.use(bodyParser.urlencoded({ extended: true }));
function convertStringX(myString, len)
{
var myBuffer = [];
var temp = Buffer.from(myString);
for (var i = 0; i < len; i++) {
// eliminate empty characters (different than spaces which are 0x20)
if (i < myString.length)
myBuffer.push(temp[i]);
else
myBuffer.push(0x0);
}
console.log(myBuffer);
return myBuffer;
}
var myPlatform;
const platformAddress = "0x...";
async function instantiatePlatform(deployedAddress) {
myPlatform = await platformContract.at(deployedAddress);
console.log("myPlatform address " + myPlatform.address);
}
instantiatePlatform(platformAddress);
app.get('/', function(req, res, next) {
// Handle the get for this route
});
app.all('/', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
next();
});
app.post('/deploy_client', (req, res, next) => {
var insurerAddress = '0x...';
var myClientUIC = req.body.clientUIC;
myClientUIC = convertStringX(myClientUIC, 16);
console.log("myClientUIC "+ myClientUIC);
var myClientName = req.body.clientName;
myClientName = convertStringX(myClientName, 16);
console.log("myClientName "+ myClientName);
var myClientGroup = req.body.clientGroup;
myClientGroup = convertStringX(myClientGroup, 16);
console.log("myClientGroup "+ myClientGroup);
var myClientNACE = req.body.clientNACE;
console.log("myClientNACE "+ myClientNACE);
var myCreditLine = parseInt(req.body.clientCreditLine);
console.log("myCreditLine "+ myCreditLine);
var myCreditLineDate = parseInt(req.body.clientCreditLineDate);
console.log("myCreditLineDate "+ myCreditLineDate);
var myClientCurrency = req.body.clientCurrency;
myClientCurrency = convertStringX(myClientCurrency, 3);
console.log("myClientCurrency "+ myClientCurrency);
var myClientCity = req.body.clientCity;
myClientCity = convertStringX(myClientCity, 32);
console.log("myClientCity "+ myClientCity);
var myClientCountry = req.body.clientCountry;
myClientCountry = convertStringX(myClientCity, 3);
console.log("myClientCountry "+ myClientCountry);
console.log("insurerAddress "+ insurerAddress);
myPlatform.createClient(myClientUIC, myClientName, myClientGroup,
myClientNACE, insurerAddress, myCreditLine, myCreditLineDate, myClientCurrency, myClientCity, myClientCountry,
{ from:provider.getAddress() })
.once('transactionHash', function(hash) {
console.log("TxHash: " + hash);
}).on('receipt', function(receipt) { console.log("receipt: " + JSON.stringify(receipt)); })
.then(function(result) {
console.log ("success - client address: " + result.address)
}, function(error) {
console.log(error);
});
});
const port = 80;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
Я действительно новичок во всей истории CORS и довольно зеленоват на глазах у серверов. Буду признателен за любую помощь, которую вы можете мне дать. Я пытался найти что-то в Интернете, но хотя я нашел много разных страниц, я не могу найти правильный ответ. Спасибо!
Решение состоит в том, чтобы добавить пакет CORS и включить:
const cors = require('cors')
app.use(cors())
, а для белого списка код:
var whitelist = ['localhost:8080']
var corsOptionsDelegate = function (req, callback) {
var corsOptions;
if (whitelist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
} else {
corsOptions = { origin: false } // disable CORS for this request
}
callback(null, corsOptions) // callback expects two parameters: error and options
}
Приведенное выше решение решает Проблема с CORS.