Michael McGarrity
Michael McGarrity

Reputation: 33

Resolve "No 'Access-Control-Allow-Origin' header is present" issue with Chrome Extension

I am developing a Chrome Extension that pre-populates fields then submits the form on an external website when I visit it.

It works perfectly when the data is hard-coded into my script.js file. However, I'd like to grab the username from an element in my Intranet home page & use this in the script instead of hard coding it.

I have made a simple script.js to test this works:

script.js:

$.get('https://intranet/index.php', function(data){ 
    alert('test');
});

When I try to use this in my Extension and reload the page, I get the error:

XMLHttpRequest cannot load https://intranet/index.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'chrome-extension://eecikfibchjhmochelhmhlimbcjglldf' is therefore not allowed access. The response had HTTP status code 401.


When this same code is run at https://intranet/test.html it works perfectly.

test.html:

<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
</head>
<script type="text/javascript">
$.get('https://intranet/index.php', function(data){ 
    $(document.body).load('https://intranet/ #username');
});
</script>

index.php:

<?php
header("Access-Control-Allow-Origin: *");
echo '<div id="username">username</div>';
?>

I have read that some use JSONP to resolve this issue. Does anyone have experience of this?

Can anyone provide help/advice on this issue?

Thank you for any guidance.

Upvotes: 3

Views: 2986

Answers (1)

Xan
Xan

Reputation: 77482

There seem to be two issues here at once.

No 'Access-Control-Allow-Origin' header is present on the requested resource.

Doesn't look like you thoroughly searched for solutions, since it's a common problem. Anyway, there are 2 ways to solve this:

  1. On the extension side. If you have host permissions, you can do cross-origin requests regardless of CORS headers. (note: "When this same code is run at https://intranet/test.html it works perfectly" highlights that the issue is cross-origin but works on the same site).

    There's a whole extension documentation article on this: Cross-Origin XMLHttpRequest, but an ultra-short version: you need to add permissions for the site in the manifest:

    "permissions": [
      "https://intranet/*"
    ],
    
  2. On the server side, by adding a Access-Control-Allow-Origin: * header. Note that this solution opens a certain attack surface (not only your extension can do requests now), so approach 1 is preferable.

That said: you tried to implement approach 2, and it didn't work. Why? Because there is a second problem:

The response had HTTP status code 401

HTTP 401 is "Unauthorized". Your requests lack the authorization necessary - which you don't see when using the intranet site itself, since the browser already have those credentials cached.

But they won't be applied to cross-origin requests, so you get a 401 error page instead of the intended page - that doesn't contain your header.

You need to provide authorization along with the request. jQuery allows that:

$.get(
  {
    url: 'https://intranet/index.php',
    username: '...',
    password: '...'
  }, function(data){ 
    alert('test');
  }
);

I think it should be obvious that this shouldn't be hardcoded in the extension.

Upvotes: 3

Related Questions