Ошибка Access-Control-Allow-Origin в журнале консоли при публикации запроса в Paypal Payflow API из приложения Angular 4 - PullRequest
0 голосов
/ 30 августа 2018

Я внедряю компонент оплаты кредитной картой в приложении Angular 4, которое использует Paypal Payflow API для обработки платежей по кредитной карте. Я уже создал тестовые и производственные учетные записи в Paypal Manager (эти учетные данные необходимо отправить в запросе API Payflow).

Согласно документации Payflow, это очень простой пример, показывающий, как отправить запрос в API Payflow:

curl https://pilot-payflowpro.paypal.com \
  -s \
  --insecure \
  -d PARTNER=PayPal \
  -d PWD=MyPassword \
  -d VENDOR=MyMerchantID \
  -d USER=MyMerchantID \
  -d TENDER=C \
  -d ACCT=5105105105105100 \
  -d TRXTYPE=S \
  -d EXPDATE=1221 \
  -d AMT=1.00

Поскольку я разрабатываю приложение для Angular, я использую библиотеку HttpClient для отправки запросов в API Payflow.

Для публикации тестовых транзакций я использую Почтальон. На Почтальоне я выполняю POST-запрос к https://pilot -payflowpro.paypal.com и отправляю что-то вроде строки ниже в теле запроса:

USER=MyUser&PARTNER=PayPal&VENDOR=MyVendor&PWD=MyPassword&ACCT=4012888888881881&EXPDATE=102020&TENDER=C&TRXTYPE=A&AMT=100&VERBOSITY=HIGH

Как только я выполняю этот запрос в Почтальоне, он прекрасно работает, и сервер возвращает ожидаемый строковый ответ, который представляет собой строку, подобную приведенной ниже:

RESULT=0&SECURETOKEN=7mHAFU7JlLEGhzUHy7VD4rQL2&SECURETOKENID=123456789123456789123456789123456781&RESPMSG=Approved

Теперь я реализовал приложение Angular 4, которое использует угловую библиотеку HttpClient для выполнения почтовых транзакций; запрос выглядит как код ниже:

private requestPayflowPaymentToPayflowGatewayApi( requestString: string ): Observable<string> {
      const headers: Headers = 
      new Headers( { 'Content-Type': 'text/plain'});
      const serverUrl = 'https://pilot-payflowpro.paypal.com';
      const body = 'USER=gtcdevelopment&PARTNER=PayPal&VENDOR=gtcdevelopment&PWD=k4l1m4nt4n&ACCT=5105105105105100&EXPDATE=102020&TENDER=C&TRXTYPE=A&AMT=100&VERBOSITY=HIGH&';

      return this.oldHttp.post(serverUrl, body, {headers: headers, responseType: ResponseContentType.Text }).catch( ( error ) => {
      console.log('error in requestPayflowPaymentToPayflowGatewayApi');
      console.error(error);
      return Observable.throw(error);
    } );
  }

Это просто основной пост-запрос, но он не работает, когда я запускаю приложение в браузере; Я получаю сообщение об ошибке ниже в журнале консоли:

Ошибка обнаружена в части .catch () наблюдаемого кода (метод post ()).

{  
   "_body":{  
      "isTrusted":true
   },
   "status":0,
   "ok":false,
   "statusText":"",
   "headers":{  

   },
   "type":3,
   "url":null
}

Вот некоторые снимки моего журнала консоли:

enter image description here enter image description here

Теперь в этом есть что-то действительно странное; Когда я отключаю веб-безопасность в Google Chrome, открывая Google Chrome с помощью приведенной ниже команды в Windows, приложение работает нормально, выполняет запрос к серверу и возвращает ожидаемый ответ.

chrome.exe --user-data-dir="C:/Chrome dev session" --disable-web-security

У меня возникает та же проблема при публикации запроса с использованием производственных данных (производственная учетная запись Paypal Manager, указывающая на https://payflowpro.paypal.com)

Кто-нибудь имел эту проблему? Как вы думаете, в этом может быть проблема здесь?

1 Ответ

0 голосов
/ 30 августа 2018

Похоже, вы столкнулись с ошибкой CORS (Cross-Origin Resource Sharing). По сути, ваш веб-браузер (все веб-браузеры) не будет отправлять запрос на сервер («источник»), который не является сервером, с которого изначально пришла ваша страница / приложение, если целевой сервер не скажет, что это нормально.

Подробнее о механике этого см. Мой предыдущий ответ на связанный, но немного другой вопрос: Ответ на предпечатный полет не имеет статуса HTTP ok в угловых

Я не знаком с API PayPal, но для этого сервер PayPal должен будет ответить на ваш запрос (на самом деле, запрос OPTION браузера) с заголовком, который сообщает вашему браузеру, что можно реально отправлять реальный запрос.

Когда вы используете опцию --disable-web-security с Chrome, вы отключаете этот процесс CORS, поэтому API работает - очень плохая идея.

Когда вы используете curl, вы также не задействуете защиту браузера CORS, и API работает.

Если нет способа заставить API возвращать правильный заголовок, чтобы запрос работал с вашего Angular-клиента на основе браузера, то единственная известная мне опция - это настроить ваш собственный процесс на стороне сервера (в тот же домен / порт, с которого обслуживается ваше приложение Angular), который передает запрос из браузера.

...