📜 ⬆️ ⬇️

Lifehack for Same-Origin-Policy; Google Chrome and others

debuger

Task:
- there is a REST server
- there is a one-page application (HTML / CSS / Javascript) which takes data from the server via XMLHttpRequest
- need to develop a new feature


')
When a front-end developer is faced with such a task, there are two options for vskidku:
- raise the test server on localhost
- ask the back-end to add the “Allow-Control-Allow-Origin: *” header to the server’s response to use XMLHttpRequest2

The first option is time consuming and not always possible. The second option is also not the best - to put "Allow-Control-Allow-Origin: *" seems to be not safe, and the back-end can do it for a long time.

And then a seemingly trivial idea occurred to me - why should I change the headers on the server, if this can be done directly on the client.

I tried to write about Fiddler once.

Fiddler Solution
Actually everything is trite and simple.
- On the tab “Filters” Turn on Use filters
- turn on “Set response header” and add the desired header “Allow-Control-Allow-Origin: *”
- enable “Set request header” is needed for Chrome; it is not needed for chrome; see below for flags in chrome

Everything!

I am afraid that if the article ended on this, the public would not have appreciated, and I’m pretending to me and the post a little less than completely, so the solution for those who do not want to have anything in common with Fiedler and who is not looking for easy ways follows.

Among the extensions for Chrome, for some reason I did not come across any one that could change the Response headers, although perhaps I was not looking well. Therefore, I decided to write my bicycle quickly. link to the extension and github because it is fashionable and youth

Chrome extension
manifest.json
{ "name": "Allow-Control-Allow-Origin: *", "version": "1.0", "manifest_version": 2, "description": "Allow to you request any site with ajax from any source. Add to response - 'Allow-Control-Allow-Origin: *' header", "background": { //      "scripts": ["background.js"] }, "browser_action": { //      , "default_popup"    "default_icon": "off.gif", "default_title": "Allow-Control-Allow-Origin" }, "permissions": [ "storage", //  localStorage "webRequest", // webRequest API "webRequestBlocking", "*://*/*" //      ], "web_accessible_resources": [ //  -             "on.gif","off.gif" ] } 

A little more detail:
- “background” - one , two briefly - in order for the extension to work when Chrome runs in the background.
In "permissions": ["*: // * / *"] you can specify the addresses of sites where the extension works and where there is access to send an ajax request from the extension. Alternative content_scripts : [...],
if you need to embed the script directly on the pages of the open site (useful if you need to use functions and variables declared in the site scripts, otherwise the extension works in its scope and the site scripts in its own)
- "browser_action" - Needed to add a button to enable and disable the extension
alternative page_action
page_action and browser_action cannot be used simultaneously
- webRequest API and webRequestBlocking - replace request and response headers
- “web_accessible_resources” - otherwise the path to the picture should look like this:
need a path:
background-image: url ("/ sprites.png");
CSS
background-image: url ('chrome-extension: //__MSG_@@extension_id__/sprites.png');
Js
var url = chrome.extension.getURL ('sprites.png');

backgound.js
 var requestListener = function(details){ var flag = false, rule = { name: "Origin", value: "http://evil.com/" }; for (var i = 0; i < details.requestHeaders.length; ++i) { if (details.requestHeaders[i].name === rule.name) { flag = true; details.requestHeaders[i].value = rule.value; break; } } if(!flag) details.requestHeaders.push(rule); return {requestHeaders: details.requestHeaders}; }; var responseListener = function(details){ var rule = { "name": "Access-Control-Allow-Origin", "value": "*" }; details.responseHeaders.push(rule); return {responseHeaders: details.responseHeaders}; }; /*On install*/ chrome.runtime.onInstalled.addListener(function(){ localStorage.active = false; }); /*Icon change*/ chrome.browserAction.onClicked.addListener(function(tab){ if(localStorage.active === "true"){ localStorage.active = false; chrome.browserAction.setIcon({path: "off.gif"}); /*Remove Response Listener*/ chrome.webRequest.onHeadersReceived.removeListener(responseListener); chrome.webRequest.onBeforeSendHeaders.removeListener(requestListener); }else{ localStorage.active = true; chrome.browserAction.setIcon({path: "on.gif"}); /*Add Response Listener*/ chrome.webRequest.onHeadersReceived.addListener(responseListener,{ urls: [ "*://*/*" ] },["blocking", "responseHeaders"]); chrome.webRequest.onBeforeSendHeaders.addListener(requestListener,{ urls: [ "*://*/*" ] },["requestHeaders"]); } }); 


More details on the code:
Callbacks for onHeadersReceived and onBeforeSendHeaders rendered responseListener and requestListener into separate functions, respectively, so that after the plug-in is turned on and off, the headers are not replaced. We remove the hung handlers.

chrome.runtime.onInstalled - run once - there you can initialize the default state of the plugin

chrome.browserAction.onClicked .addListener - when we click on the extension button - we catch the event and simulate switching on and off of the plugin

if (localStorage.active === "true") - for some reason I stumble on it every time and forget that the keys in localStorage are stored in <String>

In fact, we do not need onBeforeSendHeaders, but since Chrome does not allow sending ajax requests to localhost, we had to add.
In the first version of the extension, I did not notice this because when I run chrome, I have the flag --allow-file-access-from-files

You can read more about the flags here and here.

I have these:
Right click on the shortcut -> Properties -> Targets
C: \ Users \ Ololo \ AppData \ Local \ Google \ Chrome \ Application \ chrome.exe - allow-file-access-from-files - remote-debugging-port = 9222 - allow-file-access - allow -cross-origin-auth-prompt

As for the FF - for some reason, here too I did not find extensions for replacing the response from the server, but again I could not search well. If someone tells insert in the post.

PS
I hope you find the extension or advice useful. For those who thought it was banal and not worthy of a habr, I apologize, but at least one person was not as obvious as it became useful for you (me).
I have doubts about security, in theory with the included extension, you can score on any site from CORS , but we are all honest and will use it only for development.

Pss
The topic of the post does not apply, but maybe someone wanted and forgotten - yesterday (January 21), another round of online courses on MongoDB began
Impressions of the course can be read here . Registration for the course should be available within a couple of weeks (judging by the previous round)

Source: https://habr.com/ru/post/166539/


All Articles