Deployd - данные, полученные через AngularJS CORS
В настоящее время я читаю "Pro AngularJS" Адама Фримена. Просматривая примеры, он предлагает читателю создать приложение для спортивного магазина, используя Angular (конечно) с ресурсом сервера Deployd. Ресурс Deployd настроен для возврата данных JSON, которые должны быть заполнены в модели. Я использую NodeJS для запуска моего сервера. В настоящее время он настроен на порт 5000 (http://localhost:5000/sportsstore/app.html
). Ресурс Deployd работает на порту 5500 (http://localhost:5500/products
). При нажатии Deployd ответ выглядит следующим образом:
[
{ "name": "Kayak", "description": "A boat for one person", "category": "Watersports", "price": 275, "id": "a1c999fc248b2959" },
{ "name": "Lifejacket", "description": "Protective and fashionable", "category": "Watersports", "price": 48.95, "id": "61303717cfad182e" },
{ "name": "Soccer Ball", "description": "FIFA-approved size and weight", "category": "Soccer", "price": 19.5, "id": "0fb5f67bdcbd992f" },
{ "name": "Corner Flags", "description": "Give your playing field a professional touch", "category": "Soccer", "price": 34.95, "id": "24385d315dd388b4" },
{ "name": "Stadium", "description": "Flat-packed 35,000-seat stadium", "category": "Soccer", "price": 79500, "id": "500fb6805905a856" },
{ "name": "Thinking Cap", "description": "Improve your brain efficiency by 75%", "category": "Chess", "price": 16, "id": "637d8a1f42e6fa1c" },
{ "name": "Unsteady Chair", "description": "Secretly give your opponent a disadvantage", "category": "Chess", "price": 29.95, "id": "73393312ec7dfab7" },
{ "name": "Human Chess Board", "description": "A fun game for the family", "category": "Chess", "price": 75, "id": "7871d02a662b0915" },
{ "name": "Bling-Bling King", "description": "Gold plated, diamon-studded King", "category": "Chess", "price": 1200, "id": "b59a3389a0e248bd" }
]
Я пытаюсь извлечь эти данные с помощью $http.get
:
$http.get("http://localhost:5500/products")
.success(function (data) { ... })
.error(function (error) { ... });
Однако это продолжает возвращать ошибку:
XMLHttpRequest cannot load http://localhost:5500/products. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:5000' is therefore not allowed access.
Исследование показывает, что есть/были некоторые проблемы с Angular и CORS, и что заголовки должны были быть настроены для выполнения междоменных запросов. В результате я добавил в свой app.config следующее:
$http.defaults.useXDomain = true;
delete $http.defaults.headers.common['X-Requested-With']; // this isn't needed anymore, but was put here as a just-in-case
Несмотря на то, что эти настройки добавлены, я все еще получаю ошибку. В документации Deployd указано, что она автоматически настроена для CORS (Запросы на перекрестный поиск) и отправит соответствующую информацию заголовка, если запрос не содержит недопустимых пользовательских заголовков. Я уверен, что мой запрос не содержит недопустимых пользовательских заголовков:
Accept: application/json, text/plain, */*
Cache-Control: max-age=0
Origin: http://localhost:5000
Referer: http://localhost:5000/sportsstore/app.html
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36
Мой вопрос: есть ли какая-то другая конфигурация, которую мне нужно установить, чтобы настроить Deployd, чтобы разрешить запрос CORS? В книге не указаны какие-либо специальные настройки заголовка Angular или что-то еще.
Ответы
Ответ 1
Bic, обновите версию deployd до версии 0.6.10. Это помогло мне. Теперь я смог обработать запрос на получение. Это не похоже на ошибку с кодом AngularJS и Adam Freeman.
В книге он упоминает, что он включает программу deployd с загрузкой исходного кода на http://www.apress.com/9781430264484. Эта версия 0.6.9. Я уверен, что с ним все в порядке. Это будет проще, чем попытаться найти версию 0.6.10. Это то, что я сделал. Если вам нужна эта версия, вот она:
https://www.versioneye.com/nodejs/deployd/0.6.10
Это не инсталлятор, поэтому вам нужно вставить его в каталог deployd, заменив node_modules
.
Ответ 2
Просто запустите "обновление npm" в папке установки deployd и убедитесь, что вы обновлены до последней версии 0.6.10. Это разрешило проблему для меня после чтения ответов javaauthority (спасибо за это:)).
Ответ 3
Вы можете поместить свои файлы (app.html, sportStore.js,...) в общую папку вашего проекта deployd и использовать следующий URL-адрес
http://localhost:5500/app.html
Ответ 4
Что я сделал для решения этой проблемы, так это запуск Chrome с флагом "--disable-web-security". Но сначала зайдите в диспетчер задач и закройте каждый хромированный процесс, который у вас есть.
Ответ 5
Пока я дал правильный ответ, а другие улучшили его, что делать, если вы не используете веб-сервер Deployd, упомянутый в книге? Я использую Wildfly (JBOSS 8.X), и мне нужно было решить проблему CORS. Я создал простой Java-класс под названием CorsFilter. Импорт должен быть довольно легко найти, если вы используете Wildfly.
Надеемся, что это поможет другим людям, которые сталкиваются с подобными проблемами с разными веб-серверами.
Обратите внимание: responseContext.getHeaders(). add ( "Access-Control-Allow-Origin", "*" );
Обратите внимание на * в приведенной выше строке? Это позволит ЛЮБЫМ запросам добиться успеха. Обычно это нормально для локальных разработок, но для производственных/промежуточных сред необходимо применять более жесткие меры безопасности. Например, вы можете принимать запрос только с определенного IP-адреса.
import org.jboss.resteasy.annotations.interception.HeaderDecoratorPrecedence;
import org.jboss.resteasy.annotations.interception.ServerInterceptor;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
/**
* Class to .
* User: Java Authority
* Date: 12/6/2014
* Time: 12:38 PM
*/
@Provider
@ServerInterceptor
@HeaderDecoratorPrecedence
@WebFilter
public class CorsFilter implements ContainerResponseFilter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest r = (HttpServletRequest)request;
HttpServletResponse s = (HttpServletResponse)response;
chain.doFilter(request, response);
}
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
responseContext.getHeaders().add("Access-Control-Allow-Origin", "*");
responseContext.getHeaders().add("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
}
}
Ответ 6
Я использовал fiddler для изменения ответов от deployd. Эта ссылка покажет, как добавить настраиваемое правило для скрипача, чтобы добавить заголовок Access-Control-Allow-Origin: *
ко всем ответам. Он отлично работает.
http://www.leggetter.co.uk/2010/03/19/using-fiddler-to-help-develop-cross-domain-capable-javascript-web-applications.html
Ответ 7
Angular также отправляет пользовательские заголовки, которые отклоняет DPD, поместите это в свой код для dev, чтобы удалить их, и DPD будет работать:
delete $http.defaults.headers.common['X-Requested-With'];