diff --git a/docs/api/general.rst b/docs/api/general.rst index 7e55d621..e7c22919 100644 --- a/docs/api/general.rst +++ b/docs/api/general.rst @@ -74,28 +74,37 @@ Encoding OctoPrint uses UTF-8 as charset. - .. _sec-api-cross-origin: Cross-origin requests -=================== -To make use of the Octoprint API from websites other than the Octoprint web interface, -cross-origin resource sharing (`CORS `) must be enabled. -This is the case even when the website in question is served from a different port on the same machine, and on localhost. +===================== -To enable this feature, set the ``allowCrossOrigin`` key in ``config.yml`` to ``true``. +To make use of the OctoPrint API from websites other than the OctoPrint web interface, +cross-origin resource sharing (`CORS `_) must be enabled. +This is the case even when the website in question is served from a different port on the same machine and on localhost. + +To enable this feature, set the ``allowCrossOrigin`` key of the ``api`` section in ``config.yml`` to ``true`` or +check the corresponding checkbox in the API settings dialog. .. code-block:: yaml api: enabled: true - key: MYKEY + key: ... allowCrossOrigin: true +.. _fig-api-general-apicors: +.. figure:: ../images/settings-api-cors.png + :align: center + :alt: CORS configuration in the API settings + + Support for CORS can be enabled in the "API" settings + .. note:: - This means any browser page can send requests to the Octoprint API. Authorization is still required, however. + This means any browser page can send requests to the OctoPrint API. Authorization is still required however. -If CORS is not enabled, you will get errors similar to: +If CORS is not enabled you will get errors like the following:: -``XMLHttpRequest cannot load http://localhost:8081/api/files. No 'Access-Control-Allow-Origin' header is present on the requested resource.`` + XMLHttpRequest cannot load http://localhost:8081/api/files. No 'Access-Control-Allow-Origin' + header is present on the requested resource. diff --git a/docs/images/settings-global-api-key.png b/docs/images/settings-global-api-key.png index ddadf359..60978f9b 100644 Binary files a/docs/images/settings-global-api-key.png and b/docs/images/settings-global-api-key.png differ diff --git a/src/octoprint/server/api/__init__.py b/src/octoprint/server/api/__init__.py index ccfa1590..62675573 100644 --- a/src/octoprint/server/api/__init__.py +++ b/src/octoprint/server/api/__init__.py @@ -93,9 +93,8 @@ def beforeApiRequests(): @api.after_request def afterApiRequests(resp): - """""" - # Allow crossdomain + # Allow crossdomain allowCrossOrigin = s().getBoolean(["api", "allowCrossOrigin"]) if request.method != 'OPTIONS' and 'Origin' in request.headers and allowCrossOrigin: resp.headers['Access-Control-Allow-Origin'] = request.headers['Origin'] diff --git a/src/octoprint/server/api/settings.py b/src/octoprint/server/api/settings.py index 07195af0..b2306d9e 100644 --- a/src/octoprint/server/api/settings.py +++ b/src/octoprint/server/api/settings.py @@ -28,7 +28,8 @@ def getSettings(): return jsonify({ "api": { "enabled": s.getBoolean(["api", "enabled"]), - "key": s.get(["api", "key"]) + "key": s.get(["api", "key"]), + "allowCrossOrigin": s.get(["api", "allowCrossOrigin"]) }, "appearance": { "name": s.get(["appearance", "name"]), @@ -107,8 +108,9 @@ def setSettings(): s = settings() if "api" in data.keys(): - if "enabled" in data["api"].keys(): s.set(["api", "enabled"], data["api"]["enabled"]) + if "enabled" in data["api"].keys(): s.setBoolean(["api", "enabled"], data["api"]["enabled"]) if "key" in data["api"].keys(): s.set(["api", "key"], data["api"]["key"], True) + if "allowCrossOrigin" in data["api"].keys(): s.setBoolean(["api", "allowCrossOrigin"], data["api"]["allowCrossOrigin"]) if "appearance" in data.keys(): if "name" in data["appearance"].keys(): s.set(["appearance", "name"], data["appearance"]["name"]) diff --git a/src/octoprint/static/js/app/viewmodels/settings.js b/src/octoprint/static/js/app/viewmodels/settings.js index 77828a08..30d92698 100644 --- a/src/octoprint/static/js/app/viewmodels/settings.js +++ b/src/octoprint/static/js/app/viewmodels/settings.js @@ -6,6 +6,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) { self.api_enabled = ko.observable(undefined); self.api_key = ko.observable(undefined); + self.api_allowCrossOrigin = ko.observable(undefined); self.appearance_name = ko.observable(undefined); self.appearance_color = ko.observable(undefined); @@ -188,6 +189,7 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) { self.fromResponse = function(response) { self.api_enabled(response.api.enabled); self.api_key(response.api.key); + self.api_allowCrossOrigin(response.api.allowCrossOrigin); self.appearance_name(response.appearance.name); self.appearance_color(response.appearance.color); @@ -250,7 +252,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) { var data = { "api" : { "enabled": self.api_enabled(), - "key": self.api_key() + "key": self.api_key(), + "allowCrossOrigin": self.api_allowCrossOrigin() }, "appearance" : { "name": self.appearance_name(), diff --git a/src/octoprint/templates/settings.jinja2 b/src/octoprint/templates/settings.jinja2 index 67d4ddd6..437d0cb2 100644 --- a/src/octoprint/templates/settings.jinja2 +++ b/src/octoprint/templates/settings.jinja2 @@ -433,6 +433,13 @@ +