Теперь давайте обсудим вопросы, связанные с данными запроса браузера из разных источников. Это может быть не очень стандартно, потому что отказ от данных междоменного запроса не уникален для браузеров Причина, по которой междоменные запросы не могут быть сделаны, заключается в том, что браузеры в основном реализуют спецификацию безопасности, называемую «Политика единого происхождения». Что именно представляет собой эта спецификация? Мы нашли профиль на MDN по следующему адресу:
Объяснение политики одинакового происхождения браузера
Как правило, когда URL-адрес A и URL-адрес B находятся в协议
,端口
,域名
При наличии различий браузер активирует политику одного и того же источника и отклоняет запросы данных между серверами А и Б.
Если говорить о стратегии единоначалия, то на бумаге она поверхностна, и я абсолютно точно знаю, что это дело надо реализовать. Ниже я продемонстрирую шаг за шагом с кодом.
1. Ситуация, когда сервер А не может запросить сервер Б
Поскольку это междоменный домен, я предполагаю, что у меня есть два доменных имени, а именноA
а такжеlocalhost
,A
Указывает, что Xiaobian размещает доменное имя в облаке Alibaba.localhost
Как следует из названия, это моя машина для разработки. Мы представляем сценарий, в которомlocalhost
развернутьindex.html
файл, вA
Разверните простойspring-boot
Фоновый сервис и предоставить простой интерфейс, доступный дляindex.html
Вызов файла и, наконец, запрос браузераlocalhost
изindex.html
файл, смотрите, что подсказывает браузер?
index.html
<!DOCTYPE html>
<html>
<head>
<title>测试跨域访问</title>
<meta charset="utf-8"/>
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type : "get",
async : true,
url : "http://A/hello/map/getUser.json",// 请求A服务器上的接口
type : "json",
success : function(data) {
// 打印返回的数据
console.log("success,and return data is " + data);
}
});
});
</script>
<h2>hello world</h2>
</body>
</html>
запрос в браузереindex.html
файл, который выглядит так:
Можно обнаружить, что запрос был отклонен браузером, подсказав нам, что данные междоменного запроса не разрешены, что очень неудобно, как это решить?
2. Используйтеjsonp
Разрешить междоменные запросы
Прежде всего, поговорим о принципе, jsonp в основном использует решение междоменных проблем.<script>
Кроссдоменность тегов, т.е.src
Адрес ссылок в атрибуте может быть доступен в доменах, потому что мы частоsrc
В качестве значения атрибута задан адрес cdn, и загружена соответствующая библиотека js.
index.html
<!DOCTYPE html>
<html>
<head>
<title>测试跨域访问</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
$.ajax({
type : "get",
async : true,
jsonp : "callbackName",// 后端接口参数名
jsonpCallback : "callbackFunction", // 回调函数名
url : "http://A/hello/map/getUser.json",
dataType : "jsonp", // 数据格式为 jsonp
success : function(data) {
console.log("success");
}
});
});
</script>
<script type="text/javascript">
var callbackFunction = function(data) {
alert('接口返回的数据是:' + JSON.stringify(data));
};
</script>
</body>
</html>
A
Код интерфейса на сервере:
/**
*
* The class JsonBackController.
*
* Description:该控制器返回一串简单的json数据,json数据由一个简单的User对象组成
*
* @author: huangjiawei
* @since: 2018年6月12日
* @version: $Revision$ $Date$ $LastChangedBy$
*
*/
@RestController
@RequestMapping(value = "/map")
public class JsonBackController {
private static final Logger logger = LoggerFactory.getLogger(JsonBackController.class);
/**
* 解决跨域请求数据
* @param response
* @param callbackName 前端回调函数名
* @return
*/
@RequestMapping(value = "getUser.json")
public void getUser(HttpServletResponse response, @RequestParam String callbackName) {
User user = new User("huangjiawei", 22);
response.setContentType("text/javascript");
Writer writer = null;
try {
writer = response.getWriter();
writer.write(callbackName + "(");
writer.write(user.toString());
writer.write(");");
} catch (IOException e) {
logger.error("jsonp响应写入失败! 数据:" + user.toString(), e);
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
logger.error("输出流关闭异常!", e);
}
writer = null;
}
}
}
}
Передать параметр в бэкендcallbackName
Имя функции обратного вызова, а затем вернуть фрагмент кода js на внешний интерфейс. Формат кода js следующий:
callbackName
+ ( data
) + ;
запрос браузераlocalhost
на сервереindex.html
файл, результат такой:
Вышеупомянутый путь черезjquery + jsonp
Для решения междоменных проблем, просто не говоря о том, что его можно использовать<script>
помеченsrc
имущество? четыре.
localhost
на сервереindex.html
<!DOCTYPE html>
<html>
<head>
<title>测试跨域访问</title>
<meta charset="utf-8" />
</head>
<body>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
var callbackFunction = function(data) {
alert('接口返回的数据是:' + JSON.stringify(data));
};
</script>
<script type="text/javascript" src="http://A/hello/map/getUser.json?callbackName=callbackFunction"></script>
</body>
</html>
Эффект отображения в браузере такой же, как и выше. Но здесь следует отметить, что,src
Указывает, что вводится файл js, потому что интерфейс вызывается напрямую, а данные, возвращаемые интерфейсом, представляют собой часть кода js, поэтому его можно выполнить. Кроме того, второй<script>
Порядок меток нельзя изменить, иначе он будет отображатьсяcallbackFunction
Случай, когда функция не может быть найдена.
Код проекта:GitHub.com/smallercode…
Наконец, подводя итог, можно сказать, что существует множество решений для решения междоменной проблемы, jsonp — лишь одно из них, и конкретную ситуацию необходимо детально проанализировать. Я надеюсь, что эта статья будет вам полезна, спасибо за прочтение, добро пожаловать на githubstart
, мва!