Подтвердить что ты не робот

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 или что-то еще.

4b9b3361

Ответ 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");
    }
}

Ответ 7

Angular также отправляет пользовательские заголовки, которые отклоняет DPD, поместите это в свой код для dev, чтобы удалить их, и DPD будет работать:

delete $http.defaults.headers.common['X-Requested-With'];