首页 > 解决方案 > 将数据传递到后端(本地)服务器的“Access-Control-Allow-Origin”问题

问题描述

我遇到了 XMLHttpRequest 的问题。我有一个简单的前端加载文件并将其传递给后端以创建智能合约。如果我发出一个请求,它可以正常工作,但是当我尝试加载超过 200 行的文件时,我没有使用表单中的提交按钮,而是使用我创建的函数,我收到了 CORS 错误:

从源“ http://localhost:8080 ”访问“ http://localhost/deploy_client ”处的 XMLHttpRequest已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:否“访问控制允许” -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 问题。

标签: javascriptexpressxmlhttprequestcors

解决方案


您是否在服务器文件中尝试过cors包?当您从任何客户端向服务器发出请求时,服务器需要检查其白名单并将适当的值发送到Access-Control-Allow-Origin Header。您的服务器根本没有响应此标头。


推荐阅读