Как получить данные из веб-службы в Ajax-запросе (POST), заблокированном политикой CORS веб-браузера - PullRequest
0 голосов
/ 01 апреля 2019

Я хочу сделать Ajax-запрос методом POST к веб-сервису REST и получить от него данные, при использовании Postman запрос работает нормально, но если я использую JavaScript-фреймворк, такой как ExtJS 6 не работает, веб-сервиснаходятся в Java и на удаленном сервере.Я получаю сообщение об ошибке по политике CORS в веб-браузере.На сервере WildFly 11 настроены фильтры CORS.Как я могу получить данные из службы без блокировки CORS?

Это запрос, который я выполняю

...
Ext.Ajax.request({
            url: 'url-to-my-web-service/method1',
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            cors: true,
            useDefaultXhrHeader: false,
            withCredentials: true,
            params : {
                "user": "xxxx@xxxx.com",
                "pwd": "xzxzxzxz"
            },
            success: function(conn, response, options, eOpts) {
                var result = conn.responseText;
                console.log("success...!");
            },
            failure: function(conn, response, options, eOpts) {
                // TODO get the 'msg' from the json and display it
                console.log("error..!");
            }
        });
...

В WildFly 11 (standalone.xml)

<subsystem xmlns="urn:jboss:domain:undertow:4.0">
            <buffer-cache name="default"/>
            <server name="default-server">
                <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
                <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <filter-ref name="server-header"/>
                    <filter-ref name="x-powered-by-header"/>
                    <filter-ref name="Access-Control-Allow-Origin"/>
                    <filter-ref name="Access-Control-Allow-Methods"/>
                    <filter-ref name="Access-Control-Allow-Headers"/>
                    <http-invoker security-realm="ApplicationRealm"/>
                </host>
            </server>
            <servlet-container name="default">
                <jsp-config/>
                <websockets/>
            </servlet-container>
            <handlers>
                <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
        </handlers>
            <filters>
                <response-header name="server-header" header-name="Server" header-value="WildFly/11"/>
                <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
                <response-header name="Access-Control-Allow-Origin" header-name="Access-Control-Allow-Origin" header-value="*"/>
                <response-header name="Access-Control-Allow-Methods" header-name="Access-Control-Allow-Methods" header-value="GET, POST, OPTIONS, PUT"/>
                <response-header name="Access-Control-Allow-Headers" header-name="Access-Control-Allow-Headers" header-value="accept, authorization,  content-type, x-requested-with"/>
            </filters>
</subsystem>

Java-код (класс ws)

...
Interface interface = new ImpInterface();
    @OPTIONS
    @Consumes("application/json")
    @Path("/method1")
    public Response getToken(String clientData){
        return interface.method1(clientData);
    }
    }
...

Интерфейс

public interface Interface  {
    public Response method1(String clientData);
}

Method1

public Response method1(String clientData) {
        ...
        try {
        ...
            jsonResponse = new JSONObject().put("test", objectTest).put("value", objectTest2).toString();

            return Response
                    .status(Response.Status.OK)
                    .entity(jsonResponse)
                    .header("Access-Control-Allow-Origin", "*")
                    .header("Access-Control-Allow-Credentials", "true")
                    .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
                    .header("Access-Control-Allow-Methods", "POST, OPTIONS")
                    .build();

        } catch (Exception e) {
            ...
            return exception;
        }
}

Ошибка в консоли веб-браузера

Access to XMLHttpRequest at 'url-to-my-web-service/method1' from origin 'null' has been 
blocked by CORS policy: Cross origin requests are only supported for protocol schemes: 
http, data, chrome, chrome-extension, https.

1 Ответ

0 голосов
/ 02 апреля 2019

Первое: добавьте обработчики OPTIONS к вашему Java Code (ws class).Например:

Interface interface = new ImpInterface();
    @OPTIONS
    @Consumes("application/json")
    @Path("/method1")
    public Response getToken(String clientData){
        return Response.status(201).entity("")
        .header("Access-Control-Allow-Origin", "*")
        .header("Access-Control-Allow-Credentials", "true")
        .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
        .header("Access-Control-Allow-Methods", "POST, OPTIONS")
        .build();
    }

Далее: standalone.xml

<subsystem xmlns="urn:jboss:domain:undertow:4.0">
            <buffer-cache name="default"/>
            <server name="default-server">
                <http-listener name="default" socket-binding="http" redirect-socket="https" enable-http2="true"/>
                <https-listener name="https" socket-binding="https" security-realm="ApplicationRealm" enable-http2="true"/>
                <host name="default-host" alias="localhost">
                    <location name="/" handler="welcome-content"/>
                    <filter-ref name="server-header"/>
                    <filter-ref name="x-powered-by-header"/>
                    <filter-ref name="Access-Control-Allow-Origin"/>
                    <filter-ref name="Access-Control-Allow-Methods"/>
                    <filter-ref name="Access-Control-Allow-Headers"/>
                    <filter-ref name="Access-Control-Allow-Credentials"/> 
                    <filter-ref name="Access-Control-Max-Age"/>
                    <http-invoker security-realm="ApplicationRealm"/>
                </host>
            </server>
            <servlet-container name="default">
                <jsp-config/>
                <websockets/>
            </servlet-container>
            <handlers>
                <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
        </handlers>
            <filters>
                <response-header name="server-header" header-name="Server" header-value="WildFly/11"/>
                <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
                <response-header name="Access-Control-Allow-Origin" header-name="Access-Control-Allow-Origin" header-value="*"/>
                <response-header name="Access-Control-Allow-Methods" header-name="Access-Control-Allow-Methods" header-value="GET, POST, OPTIONS, PUT"/>
                <response-header name="Access-Control-Allow-Headers" header-name="Access-Control-Allow-Headers" header-value="accept, authorization,  content-type, x-requested-with"/>
                <response-header name="Access-Control-Allow-Credentials" header-name="Access-Control-Allow-Credentials" header-value="true"/>
                <response-header name="Access-Control-Max-Age" header-name="Access-Control-Max-Age" header-value="1"/>
            </filters>
</subsystem>

И в приложении вы должны добавить параметр типа withCredentials со значением true в вашем Ext.Ajax.request.

withCredentials information :

Свойство XMLHttpRequest.withCredentials является логическим значением, которое указывает, следует ли выполнять межсайтовые запросы Access-Control с использованием учетных данных, таких как файлы cookie, заголовки авторизации или клиентские сертификаты TLS.Настройка withCredentials не влияет на запросы одного и того же сайта.

Sencha с документациейCredentials :

Эта конфигурация иногда необходима при использовании ресурса из разных источниковПоделиться.

Пример:

Ext.Ajax.request({
            withCredentials: true,
            url: 'url-to-my-web-service/method1',
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            cors: true,
            useDefaultXhrHeader: false,
            params : {
                "user": "xxxx@xxxx.com",
                "pwd": "xzxzxzxz"
            },
            success: function(conn, response, options, eOpts) {
                var result = conn.responseText;
                console.log("success...!");
            },
            failure: function(conn, response, options, eOpts) {
                // TODO get the 'msg' from the json and display it
                console.log("error..!");
            }
        });
...