AJAX кросс-доменное полное объяснение

Java Ajax

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