Angular Ionic POST 405 (Method Not Allowed), using Chrome

1.6k views Asked by At

I managed to send a $http.post to skyscannerAPI: http://partners.api.skyscanner.net/apiservices/pricing/v1.0 However, I get the POST http://partners.api.skyscanner.net/apiservices/pricing/v1.0 405 (Method Not Allowed), I searched through Info someone said it is perhaps due to I'm using Chrome, So I installed the extension Allow-Control-Allow-Origin, but it is still showing the error. The complete error message showing that like this:

POST http://partners.api.skyscanner.net/apiservices/pricing/v1.0 405 (Method Not Allowed)
    (anonymous) @ ionic.bundle.js:25005
    sendReq @ ionic.bundle.js:24798
    serverRequest @ ionic.bundle.js:24508
    processQueue @ ionic.bundle.js:29132
    (anonymous) @ ionic.bundle.js:29148
    $eval @ ionic.bundle.js:30400
    $digest @ ionic.bundle.js:30216
    $apply @ ionic.bundle.js:30508
    (anonymous) @ ionic.bundle.js:65428
    defaultHandlerWrapper @ ionic.bundle.js:16792
    eventHandler @ ionic.bundle.js:16780
    triggerMouseEvent @ ionic.bundle.js:2953
    tapClick @ ionic.bundle.js:2942
    tapTouchEnd @ ionic.bundle.js:3069

The (anonymous) @ ionic.bundle.js:25005 is following code:

xhr.send(isUndefined(post) ? null : post);

My code is as following:

//service.js    
.service('skyscanner',function($http){
      var baseUrl= "http://partners.api.skyscanner.net/apiservices/pricing/v1.0";
      var bodyInfo= {
            body: {
              apikey: My_API_KEY,
              Country: "CA",
              Currency: "CAD",
              //more data......   
            }
          };
      this.getKey= function(){  
        var require_sessionkey= $http({
          method:"POST",
          url:baseUrl,
          data: bodyInfo,
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Accept' :'application/json'
          }
        })
        .success(function successCallback() {
          var polling={};
          var session_key = require_sessionkey.headers["location"];
          (function(){
            polling=$http.get(session_key, {query: {apikey: My_API_KEY}});  
          })();
          return polling;
        }).error(function errorCallback() {
          console.log("something gets wrong: "+ require_sessionkey);
        });
      };
    })

//controller.js   
.controller('FlightSearchCtrl',function($scope,skyscanner,FlightInfos){
          $scope.list = [];
          $scope.text = 'hello';
          $scope.skyscannerPost= function(){
            var polling=skyscanner.getKey();
            $scope.polling=polling;
          };
        })
1

There are 1 answers

0
AudioBubble On BEST ANSWER

After a couple of hours research, I found the answer. I need to serialize my data because the Content-Type: 'application/x-www-form-urlencoded', which means that the body of the HTTP message sent to the server is essentially one giant query string -- name/value pairs are separated by the ampersand (&), and names are separated from values by the equals symbol (=). An example of this would be(reference https://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data):

MyVariableOne=ValueOne&MyVariableTwo=ValueTwo

if the data is not serialized, it looks like:

 console.log(bodyInfo);
//=> Object {apikey: "ds436195492025844505223424234232173", country: "CA", currency: "CAD", locale: "zh_Hans_CN", adults: 1…}

After it is serialized:

    console.log(bodyInfoSerialied);
  //=>apikey=ds436195492025844505223424234232173&country=CA&currency=CAD&locale=zh_Hans_CN&adults=1&children=0&infants=0&originPlace=YVR&destinationPlace=SHA&outboundDate=2017-01-19&inboundDate=2017-01-23&locationSchema=Iata&cabinClass=Economy

Thanks to the answer I post the edited code below:

    .service('skyscanner',function($http){
      var baseUrl= "http://partners.api.skyscanner.net/apiservices/pricing/v1.0";
      var bodyInfo= {
              'apikey': 'ds43619549203213123211202173',
              "country": "CA",
              "currency": "CAD",
              "locale": "zh_Hans_CN",
              //...       
          };
//new added serialize().
      serialize = function(obj, prefix) {
        var str = [], p;
        for(p in obj) {
          if (obj.hasOwnProperty(p)) {
            var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
            str.push((v !== null && typeof v === "object") ?
              serialize(v, k) :
              encodeURIComponent(k) + "=" + encodeURIComponent(v));
          }
        }
        return str.join("&");
      }
//serialize the body.
      var bodyInfoSerialied = serialize(bodyInfo);
      console.log(bodyInfo);
      console.log(bodyInfoSerialied);
      this.getKey= function(){  
        var require_sessionkey= $http({
          method:"POST",
          url:baseUrl,
          headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'Accept' :'application/json'
          },
          data:bodyInfoSerialied
        })
        .success(function successCallback(require_sessionkey) {
          console.log(require_sessionkey);
          var polling={};
          var session_key = require_sessionkey.headers["Location"];
          (function(){
            polling=$http.get(session_key, {query: {apikey: 'ds43619549203213123211202173'}});  
          })();
          return polling;
        }).error(function errorCallback(require_sessionkey) {
          console.log("something gets wrong: "+ require_sessionkey);
          console.log("bodyInfoSerialied: "+ bodyInfoSerialied);
        });
      };
    })

Notice the code still gets something wrong, but the 405 error is solved at least.