AJAX кросс-доменное полное объяснение
Сегодня я узнал полное объяснение междоменного AJAX на MOOC онлайн:www.imooc.com/learn/947
Когда я собирал вопросы для интервью по AJAX, у меня на самом деле были кросс-доменные проблемы AJAX. В то время я знал, почему существуют кросс-доменные и кросс-доменные решения. Сегодня, с изучением курса, это углубилось. Здесь записывается междоменный AJAX.
Почему возникают междоменные проблемы?
Приведенная выше картина также очень понятна, потому что сам браузер ограничен в целях безопасности (тот же источник).
- Когда мы отправляем запрос XMLHttpRequest, если запрошенный домен (имя хост-домена, порт) отличается, тогда возникает междоменная проблема (клиент не может получить данные, возвращаемые сервером)
Стоит отметить, что:Междоменная проблема возникает в запросе XMLHttpRequest, то есть не будет междоменной проблемы, если это не запрос XMLHttpRequest.
- Приведу очень простой пример: при написании веб-страницы
<img = src = www.xxxx.xxxx/ >
, URL-адрес не находится в этом домене или изображение можно получить обычным способом
Идеи для решения междоменных проблем
Очевидно, междоменная проблема связана с ограничениями браузера и возникает только с XMLHttpRequest, поэтому мы можем использовать эту идею для поиска решения:
Для проблемы с браузером вы можете использовать соответствующие параметры для запуска браузера, который может решить междоменную проблему, но универсальность крайне низкая, просто поймите.
JSONP решает проблему междоменного
JSONP — это дополнение к использованию JSON, а не официальный протокол. JSONP — решение междоменных проблемпротокол
JSONP — это решение, которое сейчас редко используется (оно немного сложнее и требует модификации фонового кода), но мы можем его правильно понять.
Шаги для использования
Добавьте контроллер в серверную часть и наследуйте класс AbstractJsonpResponseBodyAdvice. Полный код выглядит следующим образом:
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
// TODO Auto-generated constructor stub
super("callback2");
}
}
Внешний ajax-запрос:
// 服务器返回的结果
var result;
$.ajax({
url: base +"/get1",
dataType: "jsonp",
jsonp: "callback2",
//是否需要缓存,如果这里没有配置缓存,那么请求的URL还会有一个参数
cache:true,
success: function(json){
result = json;
}
});
Обратите внимание, что интерфейс AJAXjsonp: "callback2",
и наш контроллерsuper("callback2");
последователен, иначе он не будет эффективен.
Принцип JSONP заключается в динамическом создании сценариев для выполнения запросов:
Недостатки JSONP:
- Изменения в коде сервера
- Поддерживается только метод GET (принцип динамического создания скрипта на запрос)
- Отправка не является запросом XMLHttpRequest (запросы XMLHttpRequest имеют много полезных функций)
Использованная литература:
CORS решает междоменные проблемы
CORS решает междоменные проблемы (то есть наш вызываемый сервер решает междоменные идеи)
Для того, чтобы понять CORS, я прямо выдержу:сегмент fault.com/ah/119000001….
В Java мы можем полностью решить междоменную проблему, написав следующий фильтр:
package com.imooc;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.buf.StringUtils;
public class CrosFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// TODO Auto-generated method stub
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
//带cookie的时候,origin必须是全匹配,不能使用*
String origin = req.getHeader("Origin");
if (!org.springframework.util.StringUtils.isEmpty(origin)) {
res.addHeader("Access-Control-Allow-Origin", origin);
}
res.addHeader("Access-Control-Allow-Methods", "*");
// 支持所有自定义头和预检命令(非简单请求会有预检命令)
String headers = req.getHeader("Access-Control-Request-Headers");
if (!org.springframework.util.StringUtils.isEmpty(headers)) {
res.addHeader("Access-Control-Allow-Headers", headers);
}
res.addHeader("Access-Control-Max-Age", "3600");
// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
упомянутый вышене простой запрос, что такое не простой запрос, можно увидеть на следующем рисунке:
Непростые запросы будут выдавать предпечатную команду (конечно, наш фильтр выше решил проблему предпечатных команд):
Фреймворк Spring
Если вы используете среду Spring, вам нужна только одна аннотация для решения междоменной проблемы.:@CrossOrigin
Уровень HTTP-сервера
В нашей коммерческой разработке общий процесс запроса выглядит следующим образом:Браузер -> HTTP-сервер (Nginx, Apache) -> Сервер приложений (Tomcat, Weblogic)
Написанные выше фреймворки Filter и Spring решаются на сервере приложений.Мы также можем решить междоменные проблемы через HTTP-серверы (Nginx, Apache)!
Я использовал Nginx, но не использовал Apache.Ниже приводится краткая запись того, как настроены Nginx и Apache:
Конфигурация Nginx:
Конфигурация апача:
Прокси для решения междоменных проблем
Как мы видели на предыдущем рисунке, решение междоменных проблем можно решить в «вызывающем».
«Вызывающий» решает междоменную проблему следующим образом:Пусть исходящий запрос прокси стоит домена
Например:
www.zhongfucheng.top是调用方
www.zhongfucheng.site是被调用方
Они из разных доменов, но мы можем сделать это на nginx или ApacheНастройте прокси: сопоставьте вызываемый адрес www.zhongfucheng.site с другим путем.
Например, как на рисунке ниже,Порт 8080 сопоставляется с ajaxServer.Когда вызывающая сторона обращается к пути ajaxServer, этот метод внешне не выглядит как междоменный, как доступ к локальному (порт 8081), а на самом деле обращается к другим доменам (порт 8080))
Суммировать
Мне проще всего решить кроссдоменную проблему через аннотации Spring.Метод JSONP используется редко из-за определенных недостатков, но разобраться в нем можно, ведь его могут спросить на собеседовании. . Когда фреймворк не используется, написать фильтр несложно, и он просто настраивается с информацией заголовка HTTP. Если вы используете Nginx и Apache, вы также можете использовать прокси-сервер или настроить информацию заголовка HTTP для решения этой проблемы. После прочтения чувствуете ли вы, что междоменная проблема решена?
Если в статье есть ошибки, пожалуйста, исправьте меня и поделитесь друг с другом. Студенты, которые привыкли читать технические статьи в WeChat, и студенты, которые хотят получить больше ресурсов по Java, могутОбратите внимание на публичный аккаунт WeChat: Java3y