为什么http://localhost:8000向http://localhost:8000发送post数据,是跨域访问?

一个python basehttpserver的服务器,挂在localhost:8000上
然后用谷歌浏览器访问这个html+js页面
到这里都没问题的
然后我尝试着让html+js页面用xmlhttprequest发送post数据到localhost:8000
然后就一直被谷歌浏览器禁止了
我协议域名端口都相同啊为什么禁我?
求dalao帮忙分析一波
这是我的js

/**
  * This module creates a 200x200 pixel canvas for a user to draw
  * digits. The digits can either be used to train the neural network
  * or to test the network's current prediction for that digit.
  *
  * To simplify computation, the 200x200px canvas is translated as a 20x20px
  * canvas to be processed as an input array of 1s (white) and 0s (black) on
  * on the server side. Each new translated pixel's size is 10x10px
  *
  * When training the network, traffic to the server can be reduced by batching
  * requests to train based on BATCH_SIZE.
  */
var ocrDemo = {
    CANVAS_WIDTH: 200,
    TRANSLATED_WIDTH: 20,
    PIXEL_WIDTH: 10, // TRANSLATED_WIDTH = CANVAS_WIDTH / PIXEL_WIDTH
    BATCH_SIZE: 1,

    // Server Variables
    PORT: "8000",
    HOST: "localhost",

    // Colors
    BLACK: "#000000",
    BLUE: "#0000ff",

    trainArray: [],
    trainingRequestCount: 0,

    onLoadFunction: function() {
        this.resetCanvas();
    },

    resetCanvas: function() {
        var canvas = document.getElementById('canvas');
        var ctx = canvas.getContext('2d');

        this.data = [];
        ctx.fillStyle = this.BLACK;
        ctx.fillRect(0, 0, this.CANVAS_WIDTH, this.CANVAS_WIDTH);
        var matrixSize = 400;
        while (matrixSize--) this.data.push(0);
        this.drawGrid(ctx);

        canvas.onmousemove = function(e) { this.onMouseMove(e, ctx, canvas) }.bind(this);
        canvas.onmousedown = function(e) { this.onMouseDown(e, ctx, canvas) }.bind(this);
        canvas.onmouseup = function(e) { this.onMouseUp(e, ctx) }.bind(this);
    },

    drawGrid: function(ctx) {
        for (var x = this.PIXEL_WIDTH, y = this.PIXEL_WIDTH; x < this.CANVAS_WIDTH; x += this.PIXEL_WIDTH, y += this.PIXEL_WIDTH) {
            ctx.strokeStyle = this.BLUE;
            ctx.beginPath();
            ctx.moveTo(x, 0);
            ctx.lineTo(x, this.CANVAS_WIDTH);
            ctx.stroke();

            ctx.beginPath();
            ctx.moveTo(0, y);
            ctx.lineTo(this.CANVAS_WIDTH, y);
            ctx.stroke();
        }
    },

    onMouseMove: function(e, ctx, canvas) {
        if (!canvas.isDrawing) {
            return;
        }
        this.fillSquare(ctx, e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
    },

    onMouseDown: function(e, ctx, canvas) {
        canvas.isDrawing = true;
        this.fillSquare(ctx, e.clientX - canvas.offsetLeft, e.clientY - canvas.offsetTop);
    },

    onMouseUp: function(e) {
        canvas.isDrawing = false;
    },

    fillSquare: function(ctx, x, y) {
        var xPixel = Math.floor(x / this.PIXEL_WIDTH);
        var yPixel = Math.floor(y / this.PIXEL_WIDTH);
        this.data[((xPixel - 1)  * this.TRANSLATED_WIDTH + yPixel) - 1] = 1;

        ctx.fillStyle = '#ffffff';
        ctx.fillRect(xPixel * this.PIXEL_WIDTH, yPixel * this.PIXEL_WIDTH, this.PIXEL_WIDTH, this.PIXEL_WIDTH);
    },

    train: function() {
        var digitVal = document.getElementById("digit").value;
        if (!digitVal || this.data.indexOf(1) < 0) {
            alert("Please type and draw a digit value in order to train the network");
            return;
        }
        this.trainArray.push({"y0": this.data, "label": parseInt(digitVal)});
        this.trainingRequestCount++;

        // Time to send a training batch to the server.
        if (this.trainingRequestCount == this.BATCH_SIZE) {
            alert("Sending training data to server...");
            var json = {
                trainArray: this.trainArray,
                train: true
            };

            this.sendData(json);
            this.trainingRequestCount = 0;
            this.trainArray = [];
        }
    },

    test: function() {
        if (this.data.indexOf(1) < 0) {
            alert("Please draw a digit in order to test the network");
            return;
        }
        var json = {
            image: this.data,
            predict: true
        };
        this.sendData(json);
    },

    receiveResponse: function(xmlHttp) {
        if (xmlHttp.status != 200) {
            alert("Server returned status " + xmlHttp.status);
            return;
        }
        var responseJSON = JSON.parse(xmlHttp.responseText);
        if (xmlHttp.responseText && responseJSON.type == "test") {
            alert("The neural network predicts you wrote a \'" + responseJSON.result + '\'');
        }
    },

    onError: function(e) {
        alert("Error occurred while connecting to server: " + e.target.statusText);
    },

    sendData: function(json) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open('POST',this.HOST +':'+ this.PORT, false);
        xmlHttp.onload = function() { this.receiveResponse(xmlHttp); }.bind(this);
        xmlHttp.onerror = function() { this.onError(xmlHttp) }.bind(this);
        var msg = JSON.stringify(json);
        //xmlHttp.setRequestHeader('Content-length', msg.length);
        //xmlHttp.setRequestHeader("Connection", "close");
        xmlHttp.send(msg);
    }
}

可能有点长,发送数据部分就是这个sendData了

 sendData: function(json) {
        var xmlHttp = new XMLHttpRequest();
        xmlHttp.open('POST',this.HOST +':'+ this.PORT, false);
        xmlHttp.onload = function() { this.receiveResponse(xmlHttp); }.bind(this);
        xmlHttp.onerror = function() { this.onError(xmlHttp) }.bind(this);
        var msg = JSON.stringify(json);
        //xmlHttp.setRequestHeader('Content-length', msg.length);
        //xmlHttp.setRequestHeader("Connection", "close");
        xmlHttp.send(msg);
    }

浏览器调试信息

XMLHttpRequest cannot load localhost:8000. Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.
sendData @ ocr.js:148
train @ ocr.js:107
onclick @ (index):13
ocr.js:148 Uncaught DOMException: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'localhost:8000'.
    at Object.sendData (http://localhost:8000/ocr.js:148:17)
    at Object.train (http://localhost:8000/ocr.js:107:18)
    at HTMLInputElement.onclick (http://localhost:8000/:13:73)
sendData @ ocr.js:148
train @ ocr.js:107
onclick @ (index):13
阅读 8.3k
1 个回答

注意到一点,你的发送地址写的:

xmlHttp.open('POST',this.HOST +':'+ this.PORT, false);

你使用调试工具看一下,地址是 localhost:8000 ?

你这个没有 http://localhost

没有 http:// 会被当做 http://localhost/localhost ,这和 a标签跳转是一样的。

<a href ='http://locahost'>Link</a>

<a href ='locahost'>Link</a>

感谢 @雪狼骑兵 指正

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题