Как правильно настроить обратный прокси с Apache, который будет использоваться для междоменного AJAX?

Необходимость разработки веб-приложения, которое в то же время сильно зависит от API, но в то же время не может находиться в том же домене, что и сам API, было довольно сложно обойти "политику одинакового происхождения" при создании асинхронные HTTP-запросы (AJAX). В какой-то момент мне было рекомендовано установить WAMP на моем компьютере (под управлением Windows 7) и настроить обратный прокси с Apache. Тот же самый человек дал мне директивы Apache, которые я добавил в файл httpd.conf, после того, как сказал мне создать псевдоним для IP 127.0.0.1 с именем dev, в файле c:\windows\system32\drivers\etc\hosts ( что я и сделал):

LoadModule headers_module modules/mod_headers.so
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_connect_module modules/mod_proxy_connect.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule ssl_module modules/mod_ssl.so

Listen 127.0.0.1:8080
ProxyRequests off

<Proxy *>
                Order deny,allow
                Deny from all
                Allow from 127.0.0.1
</Proxy>

<VirtualHost dev:8080>
                ProxyPass / https://app.somesite.com:5002/
                ProxyPassReverse / https://app.somesitecom:5002/
                ProxyPassReverseCookieDomain app.somesite.com dev
                Header edit Location ^https://dev(:8080)?(.+)$ http://dev$1$2
                Header edit Set-Cookie "(^.+); secure; HttpOnly$" "$1; HttpOnly"
                SSLProxyEngine on
    SSLProxyVerify none
</VirtualHost>

Поскольку я полный новичок, когда дело доходит до настройки серверов, я просто вставлял директивы и, к счастью, достаточно, прокси работал. Он возвращает правильный ответ API, когда я использую адресную строку браузера для доступа, например, http://dev:8080/a/w/currencies.

К сожалению, хотя запрос AJAX на тот же URL-адрес (ниже приведенный ниже код) заставляет Chrome дать мне ошибку XMLHttpRequest cannot load http://dev:8080/a/w/currencies. Origin http://dev is not allowed by Access-Control-Allow-Origin..

$.ajax({
    url: "http://dev:8080/a/w/currencies",
    type: "GET",
    dataType: "json",
    data: {

    },
    success: function(data){
        console.log(data);
    }
}); 

Итак, что еще нужно сделать, чтобы этот прокси работал с AJAX? Мне рассказали что-то о директиве alias, но не достаточно конкретны и понятны, поэтому это не имело большого смысла для моего неопытного мозга.

PS: Также мне сказали: "Проблема в том, что вы получаете файлы с dev: 80 и ajaxing для dev: 8080". Учитывая мою неопытность, это не имеет большого значения.

Ответ 1

У вас есть сервер с общедоступным IP-адресом, и на нем выполняется apache. Теперь вы хотите размещать свои приложения в локальной сети, а также хотите, чтобы они были доступны в Интернете, важной частью является то, что эти приложения все еще работают на компьютерах LAN.

                           |--------------192.168.1.3
                           |            (internal3.example.com)
                           |
                           |--------------192.168.1.4
                           |            (internal4.example.com)
  (Public IP )             |
            A--------------|
(reverse proxy server)     |
  (192.168.1.25)           |
example.com                |
                           |--------------192.168.1.1
                           |            (internal1.example.com)
                           |
                           |--------------192.168.1.2
                           |            (internal2.example.com)

Я использую Ubuntu для размещения Apache vhost definition в случае систем на базе Debian, определение веб-сайтов выполняется на

/и т.д./apache2/сайты с поддержкой /*. Конф

где * conf соответствует

internal1.conf internal2.conf internal3.conf internal4.conf

Определение vhost каждого из этих сайтов будет следующим:

/etc/apache2/sites-enabled/internal1.example.conf

  ServerAdmin [email protected]
  ServerName internal1.example.com
  ProxyRequests off
  <proxy *>
  Order deny,allow
  Allow from all
  </proxy >
  ProxyPass / http://192.168.1.1/
  ProxyPassReverse / http://192.168.1.1/ </VirtualHost >

/etc/apache2/sites-enabled/internal2.example.conf

<virtualhost *:80>

      ServerAdmin [email protected]
      ServerName internal2.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.2/
      ProxyPassReverse / http://192.168.1.2/
</VirtualHost >

/etc/apache2/sites-enabled/internal3.example.conf

<virtualhost *:80>

      ServerAdmin [email protected]
      ServerName internal3.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.3/
      ProxyPassReverse / http://192.168.1.3/
</VirtualHost >

/etc/apache2/sites-enabled/internal4.example.conf

      ServerAdmin [email protected]
      ServerName internal4.example.com
      ProxyRequests off
      <proxy *>
      Order deny,allow
      Allow from all
      </proxy >
      ProxyPass / http://192.168.1.4/
      ProxyPassReverse / http://192.168.1.4/
</VirtualHost >

Обратите внимание, что во всех приведенных выше определениях vhost я сбросил параметры файлов журнала. Поэтому, если вы применитесь к производственному серверу, добавьте их в каждый файл vhost. Выше всего, чтобы дать вам четкий пример того, как он может работать. Я запускаю очень сложную установку Apache, поэтому выше всего лишь небольшой пример, который поможет вам.

Теперь, придя в Ajax, часть вашего вопроса

в хром нажмите Ctrl + Shift + я вы увидите, где именно приложение сломано, он даст вам некоторую подсказку, (выдаст запрос с машины, отличной от машины, на которой вы разрабатываете веб-приложение). также если вы можете посмотреть журналы apache, если запрос с страницы http://sample, который имеет ajx api, фактически достиг вашего сервера apache, который даст вам больше подсказок, если прокси перенаправляет ваш запрос правильно, отправьте HTTP HEADERS с помощью некоторого инструмента в firefox как live_http в состоянии, когда не было запроса и условия, когда запрос был выполнен приложением таким образом, наблюдая за заголовками, вы можете помочь вам, если запрос достиг сервера за обратным прокси-сервером, также проверьте журналы сервера, который запущен обратный прокси-сервер, если запрос из сети достиг этого или нет, и если запрос достигнет того, что было запрошенным URL. Это даст вам ключ,

и для целей разработки в ваших .conf файлах отключите правила перезаписи в течение некоторого времени для проверки, сделайте это один за другим.

Ответ 2

Проблема заключается в том, что браузер пытается защитить вас от того, что вы нарисовали случайным javascript, размещенным на какой-либо веб-странице. Если бы он позволял всем javascript запускаться в том же контексте, вы потеряли бы куки файлы Facebook или другие данные плохим парням.

В этом случае виновником может быть что-то настолько простое, что Chrome не считает, что "dev" является Полностью квалифицированным доменным именем, поэтому он не сможет выполнить те же тесты происхождения. Другая причина может заключаться в том, что в какой-то момент вы получаете материал из app.somesite.dev, и в какой-то момент вы отправляете запросы на "dev"

Серверы не заботятся о том, что они отправляют, и это браузер, который вам нужен, чтобы обмануть, чтобы все происходило от одного и того же хоста.

  • Я бы заменил "dev" в файле hosts dev.example.com 127.0.0.1
  • Я бы удостоверился, что все, что выходит из прокси-сервера Apache, относится только к dev.example.com независимо от того, с какого сервера он приходит.
  • Используйте только код dev.example.com в коде

Если все остальное не удается, вы можете добавить HTTP-заголовок "Access-Control-Allow-Origin: *", чтобы разрешить любое происхождение, но я бы не использовал его, кроме как только в dev-средах.

PS. Даже если вы получите javascript из example.com:80, что javascript не может даже вызвать example.com:443 или javascript из example.com не может сделать xmlhttprequests для dev.example.com

Ответ 3

на 127.0.0.1, ваш html-код должен быть:

$.ajax({
    url: "http://127.0.0.1/a/w/currencies",
    type: "GET",
    dataType: "json",
    data: {
    },
    success: function(data){
        console.log(data);
    }
}); 

на 127.0.0.1, ваш apache conf должен быть:

...

<VirtualHost dev:8080>
            ...
            ProxyPass / https://app.somesite.com:5002/
            ProxyPassReverse / https://app.somesitecom:5002/
            ...
</VirtualHost>

в этом случае ваш браузер не будет междоменным, потому что ваш url и ajax используют один и тот же домен. Но точно, ajax-запрос https://app.somesite.com:5002/, я не знаю, является ли это обратным прокси-сервером, но для меня это работает. Попробуйте:)

Ответ 4

Я сам буду пытаться сделать то же самое, вот как я нашел этот поток.

Интересно, неверен ли фактический URL-адрес, который вы используете в запросе AJAX. По сути, вы подключаетесь к прокси. Он отправляет вам адрес порта 8080. Затем вы пытаетесь сделать запрос AJAX непосредственно на адрес 8080? Относительная ссылка может работать так, чтобы вызов AJAX пересылался по одному и тому же пути, чтобы javascript знал, что он имеет одинаковое происхождение.

Альтернативой является поддержка с PHP. Лекция 7 этого онлайн-курса охватывает AJAX и делает пример с PHP, чтобы полностью обойти ограничения одного происхождения. http://academicearth.org/courses/building-dynamic-websites/

Я только что нашел это, похоже, лучшее решение. http://darius.kruythoff.net/blog/2011/xss-with-apache/