Не обрабатывать "Access-Control-Allow-Origin" - проблемы на стороне клиента

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

У меня есть клиентский код моего веб-сайта, развернутый на сервере, и этот веб-сайт вызывает веб-сервис, развернутый на каком-то другом другом сервере. (Обратите внимание: у меня нет доступа к коду этого веб-сервиса).

Мой код AJAX для получения данных:

$.ajax({
        type: 'GET',
        url: 'http://webservice_url',
        success: function (data) {
             //success
        },
        failure: function(error){
            //error
        }
    });

При доступе к этому веб-сервису через AJAX я получаю:

XMLHttpRequest cannot load http://webservice_url. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.

Журнал консоли браузера:

  • Я могу успешно просмотреть ответ своего веб-сервиса в консоли браузера (на вкладке «Сеть» -> вкладка «Ответ» моего веб-сервиса). Тем не менее, получение вышеуказанной ошибки.

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

response.addHeader("Access-Control-Allow-Origin", "*");

исправит эту проблему.

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

Я разработал этот веб-сайт с помощью ExpressJS и Node. Мой код приложения

var http = require('http');
var routes = require('./routes');
var express = require('express');
var path = require('path');

var app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
app.use(express.cookieParser('secret code'));
app.use(express.logger('dev'));
app.use(express.favicon());
app.use(express.methodOverride());
app.use(express.session());
app.use(express.bodyParser());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// Add headers
app.use(function (req, res, next) {
    // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', '*');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Pass to next layer of middleware
    next();
});

app.get('/', routes.index);

http.createServer(app).listen(3000, function(){
    console.log('Express server started successfully');
});

Добавление res.setHeader('Access-Control-Allow-Origin', '*') мне не помогло.

Может ли кто-нибудь направить меня.


person Community    schedule 22.01.2014    source источник
comment
Если у вас нет доступа к веб-сервису, то вы, очевидно, не можете изменить то, какие заголовки ответов он генерирует — и, следовательно, вы не можете использовать междоменный AJAX. Проверьте их документы, если они предлагают другие способы запроса данных, например. JSONP.   -  person CBroe    schedule 22.01.2014


Ответы (1)


Это связано с междоменными ограничениями.

Вы добавили Access-Control-Allow-Headers в свой клиентский код, что неверно. Его следует добавить в серверный код, то есть в ваш веб-сервис, к которому вы пытаетесь подключиться.

Однако, поскольку у вас нет доступа к этой веб-службе, вы можете использовать jQuery ajax, как показано в этом ответе.

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     jsonp: 'callback',
     jsonpCallback: 'jsonpCallback',
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     },
});

function jsonpCallback(data){
    alert("jsonpCallback");
}

Или используйте альтернативную функцию, описанную здесь

Чтобы использовать jsonp, веб-служба должна поддерживать параметр обратного вызова, ознакомьтесь с их документацией.

person Salman    schedule 22.01.2014
comment
Спасибо за быстрый ответ. Теперь я понимаю, почему «Access-Control-Allow-Headers» у меня не сработал. Я пробовал с «jsonp». Теперь я не получаю ошибку No 'Access-Control-Allow-Origin' в консоли! Однако я все еще не могу получить данные ответа в блоке успеха AJAX. При исследовании моего веб-сервиса в консоли браузера (на вкладке «Сеть» -> вкладка «Ответ» моего веб-сервиса) я получаю действительный ответ. Однако в «URL-адресе запроса» есть некоторый обратный вызов. Как MY_WEBSERVICE?callback=jQuery19104137628001626581_1139105641 - person ; 22.01.2014
comment
Вот как работает обратный вызов в jsonp. Вы должны передать обратный вызов, как я показал в обновленном ответе. Этот обратный вызов идет как параметр строки запроса, и ws должен заключать ответ в функцию обратного вызова. - person Salman; 22.01.2014
comment
Привет CanMAH, извините, если мой вопрос глупый. Я новичок в JSONP. Я использовал ваш пример кода. Однако функция jsonpCallback не вызывается у меня при успешном ответе. Вы упомянули об использовании JSONP, когда веб-сервисы поддерживают параметр обратного вызова. Я думаю, что мои веб-сервисы не поддерживают jsonp (потому что функция jsonpCallback не вызывается для меня на стороне клиента). Пожалуйста, поправьте меня, если я ошибаюсь. Поскольку я не контролирую код своего сервера (веб-сервисы), я не могу изменить этот веб-сервис для обработки типа jsonp. Есть ли у меня другая душа для работы на стороне клиента. Еще раз спасибо за ваше время. - person ; 22.01.2014
comment
jsonp не работает без обратного вызова, я не думаю, что есть какое-либо другое решение, кроме этого. - person Salman; 22.01.2014
comment
Почему бы вам не создать прокси-метод на своем сервере, который принимает ваши запросы ajax, делает запросы к этой веб-службе? - person Salman; 22.01.2014
comment
Я говорю о том же сервере node, на котором работает ваш код ajax. Сделайте там прокси-функцию, которая принимает запросы от ajax и отправляет запрос в веб-сервис. междоменные ограничения находятся в браузере, а не на сервере node.js, поэтому вы можете легко получить доступ к веб-службе и ответить на ее ответ. - person Salman; 23.01.2014
comment
В сообщении stackoverflow.com/questions/20323332/, он объяснил, что с помощью http-прокси междоменные ограничения фиксируются на сервере узла. Я следовал тому же коду (доступному в его вопросе), и теперь проблема с междоменными доменами исправлена. Теперь у меня есть аналогичная настройка прокси-сервера между этими двумя серверами. Следовательно, без прокси-сервера я могу успешно получить доступ к веб-сервисам. Однако, если у меня есть прокси-сервер между веб-сайтом и веб-службой (серверами), я получаю 500 Internal Server NetworkError. Не могли бы вы помочь мне в этом? - person ; 23.01.2014