Jump to content

Accessing The Api From Angularjs: Method Options Is Not Valid


MySteRe13

Recommended Posts

Hi,
 
I am trying to get some data from my PrestaShop web service, the carriers for example:

GET http://shop/api/carriers?ws_key=xxx

Using my Chrome RestClient, it's working as expected.

 
Now, from my AngularJS app, requesting the resource, a preflight request is made just before the GET. This preflight request is called with the OPTIONS verb. The debugger says:

OPTIONS http://shop/api/carriers?ws_key=xxx 
XMLHttpRequest cannot load http://shop/api/carriers?ws_key=xxx . Response for preflight has invalid HTTP status code 405

Trying an OPTIONS call directly from the Chrome RestClient, gives me (with MODE_DEV on):

<prestashop>
  <errors>
    <error>
      <code> <![CDATA[23]]> </code>
      <message> <![CDATA[Method OPTIONS is not valid]]> </message>
    </error>
  </errors>
</prestashop>

My root .htaccess contains thoses lines:

Header add Access-Control-Allow-Origin "*"
Header add Access-Control-Allow-Headers "origin, x-requested-with, content-type"
Header add Access-Control-Allow-Methods "PUT, GET, POST, DELETE, OPTIONS"

I don't know what to do now. Is this problem coming from the client, the PrestaShop or the hosting server configuration? Running the AngularJS client from localhost or from the PrestaShop server gives me the same error.

 

Any idea?

 

Thank you

 

Link to comment
Share on other sites

Solved by adding in the .htaccess:

<IfModule mod_headers.c>
   Header always set Access-Control-Allow-Origin "*"
   Header add Access-Control-Allow-Headers "Content-Type, Authorization"
   Header always set Access-Control-Allow-Methods "GET,POST,HEAD,DELETE,PUT,OPTIONS"
</IfModule>

Angular side:

delete $http.defaults.headers.common.Authorization;
$http({
   method: 'GET',
   url: 'http://shop/api/carriers',
   headers: {
      'Accept': 'application/xml',
      'Content-Type': 'application/xml'
   },
   params: {
      ws_key: 'xxx'
   }
}).then(successFn, errorFn);
Edited by MySteRe13 (see edit history)
  • Like 1
Link to comment
Share on other sites

  • 4 months later...

I solved by adding in webservice/dispatcher.php this lines of code, after "require_once(dirname(__FILE__).'/../config/config.inc.php');":

// respond to preflights
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
  // return only the headers and not the content
  // only allow CORS if we're doing a GET - i.e. no saving for now.
  if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD']) && $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'] == 'GET') {
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Headers: X-Requested-With');
  }
  exit;
}

The following PHP code simply checks for the OPTIONS request method. If OPTIONS has been used to make the request, and the user is requesting using CORS, my server responds saying that the X-Requested-With header is permitted.

Solution found here: https://remysharp.com/2011/04/21/getting-cors-working

 

Note that allow CORS only if we're doing a GET, so add other methods in the condition above to handle them.

 

It is not necessary to insert this lines in .htaccess:

<IfModule mod_headers.c>
   Header always set Access-Control-Allow-Origin "*"
   Header add Access-Control-Allow-Headers "Content-Type, Authorization"
   Header always set Access-Control-Allow-Methods "GET,POST,HEAD,DELETE,PUT,OPTIONS"
</IfModule>

because the OPTIONS method is permitted, and also Content-Type and Authorization headers.

 

As MySteRe13 said "an empty Authorization header was send", but it was empty in OPTIONS message that ask for permission.

If we respond to OPTIONS message with an HTTP status code 200, then Angular sent another message with Authorization header and GET method.

 

Other details here: http://stackoverflow.com/questions/36353532/angular2-options-method-sent-when-asking-for-http-get

 

 

I hope that this response will be useful

Link to comment
Share on other sites

  • 3 years later...

i modified like this

 

if ($method === 'OPTIONS') {
    die('200');
    ob_end_flush();
}else{
    if (isset($_SERVER['PHP_AUTH_USER'])) {
    $key = $_SERVER['PHP_AUTH_USER'];
} elseif (isset($_GET['ws_key'])) {
    $key = $_GET['ws_key'];
} else {
    header($_SERVER['SERVER_PROTOCOL'].' 401 Unauthorized');
    header('WWW-Authenticate: Basic realm="Welcome to PrestaShop Webservice, please enter the authentication key as the login. No password required."');
    die('401 Unauthorized');
}
    

4 firsts lines added and it worked then

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...