【问题标题】:Disabling same origin policy for Chrome for local domains为本地域禁用 Chrome 的同源策略
【发布时间】:2015-12-08 15:16:27
【问题描述】:

我正在尝试在我的 Mac OS 10.10 机器上使用 Chrome 45.0.2454.85(64 位)在本地 *.dev 样式域上执行跨源请求,以实现我正在开发的扩展。

我无法通过testbox.dev 收到消息,因为每次执行以下代码时,我都会获得status 的值0,而responseText 始终为空。检查后台页面的视图会在尝试这些连接时显示控制台错误net::ERR_CONNECTION_REFUSED

我尝试关闭所有 Chrome 实例,然后使用命令 open -a Google\ Chrome --args --disable-web-security 重新启动,但仍然无法正常工作。

我尝试了CORS Chrome 扩展,所以我至少可以在本地服务器上进行测试,但是没有用。

尝试在我的实时api.example.com URL 前加上https://www.corsproxy.com/,但请求永远不会完成。

尝试使用cors-anywhere.herokuapp.com 前缀,但我得到了错误origin header required。为了解决这个问题,我尝试使用 xhr.setRequestHeader('Origin', http + '//' + window.location.host); 发送原始标头,但 Chrome 不允许我继续处理错误 Refused to set unsafe header "Origin"

我尝试将以下响应添加到服务器的 Laravel 控制器方法中,但没有帮助:

return Response::json($stock, 200, ['Access-Control-Allow-Origin' => '*']);

manifest.json:

{
    "name": "__MSG_appName__",
    "version": "1.0.0",
    "manifest_version": 2,
    "description": "__MSG_appDescription__",
    "icons": {
        "16": "images/icon-16.png",
        "48": "images/icon-48.png",
        "128": "images/icon-128.png"
    },
    "default_locale": "en",
    "background": {
        "scripts": [
            //"scripts/chromereload.js"
            "scripts/background.js"
        ],
        "persistent": false
    },
    "browser_action": {
        "default_icon": {
            "16": "images/icon-16.png",
            "32": "images/icon-32.png",
            "38": "images/icon-38.png",
            "48": "images/icon-48.png",
            "64": "images/icon-64.png",
            "128": "images/icon-128.png"
        },
        "default_title": "Workflow Enhancer"
    },
    "options_page": "options.html",
    "content_scripts": [
        {
            "matches": [
                "http://www.example.com/*",
                "https://www.example.com/*",
                "https://*.freshbooks.com/*",
                "https://*.highrisehq.com/*"
            ],
            "css": [
                "styles/content.css"
            ],
            "js": [
                "scripts/jquery.min.js",
                "scripts/xhrproxy.js",
                "scripts/content.js"
            ],
            "run_at": "document_end",
            "all_frames": false
        }
    ],
    "permissions": [
        "activeTab",
        "<all_urls>",
        "http://*.dev/*",
        "https://*.dev/*",
        "http://testbox.dev/*",
        "https://testbox.dev/*",
        "http://*.example.com/*",
        "https://*.example.com/*"
    ],
    "web_accessible_resources": [
        "*"
    ]
}

background.js

chrome.extension.onConnect.addListener(function(port) {
    if (port.name != 'XHRProxy_')
        return;

    port.onMessage.addListener(function(xhrOptions) {
        var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');
        var xhr = new XMLHttpRequest();

        xhr.open(xhrOptions.method || "GET", http + xhrOptions.url, true);
        //xhr.setRequestHeader('Origin', http + '//' + window.location.host);
        xhr.setRequestHeader('X-Requested-With', 'XHRProxy');
        xhr.setRequestHeader('X-API-key', 'JSFLIESLIFDFDHSLFEHSLFHSFH');

        xhr.onreadystatechange = function() {
            if (this.readyState == 4) {
                port.postMessage({
                    status : this.status,
                    data   : this.responseText,
                    xhr    : this
                });
            }
        };

        xhr.send();
    });
});

xhrproxy.js

var proxyXHR = {};

proxyXHR.get = function (url) {
    var port     = chrome.extension.connect({ name: 'XHRProxy_' });
    var settings = {
        method : 'GET',
        url    : url
    };
    var onSuccess;
    var onFailure;
    var self = {
        onSuccess: function (callback) {
            onSuccess = callback;
            return self;
        },
        onFailure: function (callback) {
            onFailure = callback;
            return self;
        }
    };
    port.onMessage.addListener(function (msg) {
        if (msg.status === 200 && typeof onSuccess === 'function') {
            onSuccess(msg.data, msg.xhr);
        } else if (typeof onFailure === 'function') {
            onFailure(msg.data, msg.xhr);
        }
    });
    port.postMessage(settings);
    return self;
};

content.js

// Localhost test domain.
proxyXHR.get('testbox.dev/api/XYZ/quantity')
            .onSuccess(function (data) {
                console.log(data);
            })
            .onFailure(function (data, xhr) {
                console.log("HTTP Error while retrieving data.", data, xhr.status);
            });

// Production server domain....produces same error as local domain test above.
proxyXHR.get('api.example.com/api/XYZ/quantity')
            .onSuccess(function (data) {
                console.log(data);
            })
            .onFailure(function (data, xhr) {
                console.log("HTTP Error while retrieving data.", data, xhr.status);
            });

如果我将 URL 从 testbox.dev 更改为我的生产 URL api.example.com,我仍然会收到相同的跨源拒绝。

有什么想法吗?

【问题讨论】:

  • 你的扩展清单是什么?您是否将本地域添加到 permissions 部分?
  • 请发布您的清单文件。
  • @rsanchez 是的,我将其添加到权限中。清单文件已添加到帖子中。
  • net::ERR_CONNECTION_REFUSED 不是跨域错误。您的https 连接可能有问题。
  • 您是从扩展程序的后台页面发出请求,而不是从 https 页面发出请求。如果您在清单中设置了权限,则没有政策禁止通过 http 进行 xhr。

标签: javascript google-chrome google-chrome-extension xmlhttprequest cross-domain


【解决方案1】:

net::ERR_CONNECTION_REFUSED 不是跨域错误。您的 https 连接可能有问题。您可以确保您的服务器上有正确的证书或切换到 http。

注意下面一行:

    var http = (window.location.protocol === 'http:' ? 'http:' : 'https:');

在后台页面中没有多大意义,因为协议总是chrome-extension:

【讨论】:

  • 就是这样!追逐错误的错误总是很有趣。
猜你喜欢
  • 2014-02-05
  • 2015-12-27
  • 2014-03-28
  • 2012-08-29
  • 1970-01-01
  • 2013-06-09
相关资源
最近更新 更多