English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Обобщение знаний о доступе через границы источников JS
До того как слово "доступ через границы источников" стало часто встречаться, мы уже часто использовали его. Например, img src A веб-сайта указывает на адрес изображения B веб-сайта,毫无疑问, в обычных случаях это всегда будет нормально отображаться (не говоря уже о технологии защиты от воровства ссылок); таким же образом, можно указать свойство src тега script на ресурсы скрипта других веб-сайтов (в некоторых случаях даже поощряется это делать, чтобы充分利用 преимущества нагрузки других веб-сайтов, уменьшить нагрузку на свой собственный сервер). Однако, если использовать js для активного запроса данных с других веб-сайтов, например, с помощью метода Ajax, встретится досадная проблема доступа через границы источников, которую мы обычно называем доступом через границы источников. Из соображений безопасности доступ через границы источников по умолчанию запрещен большинством браузеров. Это связано с концепцией политики источников: политика источников предотвращает загрузку скриптов из одного источника для получения или операции свойств документа другого источника. Иначе говоря, домен запрашиваемого URL должен быть тем же, что и домен текущей веб-страницы. Это означает, что браузер изолирует содержимое из различных источников, чтобы предотвратить их взаимодействие.
Конкретные安全问题, связанные с доступом через границы источников, блогер не анализировал, все могут自行 додумать.
Однако, в多くе случаев, особенно в условиях постоянного развития интернета сегодня, нам нужно запрашивать интерфейсы на переднем конце от различных партнеров или поставщиков данных. До того как способ доступа через границы источников будет стандартизирован (кажется, что потребность в доступе через границы источников на клиентской стороне также привлекла внимание W3C, говорят, что стандарт WebSocket HTML5 поддерживает обмен данными через границы источников, и это также может быть одним из будущих решений для обмена данными через границы источников), как можно обойти его ограничения? Ответов много (хотя все они сложны), наиболее часто используемый - это так называемый JSONP через границы источников.
Принцип JSONP
Основной принцип JSONP заключается в динамическом добавлении тега <script>, у которого свойство src не имеет ограничений на границы источников. Таким образом, этот способ через границы источников не имеет отношения к протоколу XmlHttpRequest, известному как Ajax.
JSONP означает JSON сpadding. Из-за ограничений политики источников, XmlHttpRequest позволяет запрашивать ресурсы только из текущего источника (домен, протокол, порт). Если нужно выполнить запросы через границы источников, можно использовать тег script html для выполнения запросов через границы источников и в ответе возвращать выполняемый код script. Этот способ коммуникации через границы источников называется JSONP.
Пример: прост
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <head> <title>Test Jsonp</title> <script type="text/javascript"> function jsonpCallback(result) { alert(result.msg); } </script> <script type="text/javascript" src="http://crossdomain.com/jsonServerResponse?jsonp=jsonpCallback"></script> </head> <body> </body> </html>
Краткое описание принципов и процесса: сперва регистрируем callback на клиенте, затем передаем имя callback серверу (здесь клиент и сервер согласуют передачу значения key как строкового значения jsonp). В этот момент сервер создает json-данные. Затем сервер создает функцию, используя синтаксис javascript, имя функции соответствует переданному параметру jsonp. Наконец, json-данные передаются в качестве аргумента в функцию, таким образом создается документ в формате js, который передается клиенту. Браузер клиента анализирует тег script и выполняет возвращенный javascript-документ, что эквивалентно выполнению предварительно определенного callback-функции.
Из краткого описания можно сделать вывод: помимо возвращения фрагментов js-кода в виде функции, сервер естественно может возвращать все выполнимые фрагменты js, соответствующие стандарту.
Недостатки JSONP: он поддерживает только запросы GET, а не POST и другие типы HTTP-запросов; он поддерживает только запросы HTTP через границы домена, и не решает проблему вызова JavaScript между страницами в разных доменах. (Ниже есть продолжение)
jQuery Jsonp
Как уже упоминалось ранее, jsonp не является запросом ajax, но jQuery предоставляет способ выполнения запросов через границы домена, аналогичный jQuery.ajax:
$.ajax({ url: 'http://crossdomain.com/jsonServerResponse', type: 'GET', dataType: 'jsonp', jsonp: "callback", jsonpCallback: 'functionName', success: function (data, textStatus, jqXHR) { } //…… });
如上所示,dataType设为jsonp表示这是一次跨域请求,jsonp设为服务端预定的传递函数名称的查询字符串key,而jsonpCallback即为js函数名称;假如jsonpCallback不设置,那么jQuery将自动生成的随机函数名(在window对象中加载一个全局的函数,当代码插入时函数执行,执行完毕后就会被移除),可推断该自动生成的函数会回调上述代码中的success函数。(当手动为jsonpCallback赋值时,不知道success函数会否回调,还是说jQuery会寻找预定义的函数,若找不到则报错?博主懒,以后再试吧。)当然jQuery为我们提供了一个简易版本,$.getJSON,这里就不赘述了。
需要注意的是success函数中的jqXHR参数,在ajax请求中,它是正宗的jqXHR对象,亦可看作是XMLHTTPRequest对象(继承或封装),但是在jsonp请求中却并非如此,几乎不能带给我们如XMLHTTPRequest中最有用的那些信息:它缺少XMLHTTPRequest的请求状态信息,所以并不能触发绝大部分的回调函数,比如error、complete等(jQuery1.9.0),而可以被回调的success函数推测应该是由script标记的load事件触发,这也同ajax依靠XMLHTTPRequest的状态的机制完全不同。经试验,脱胎于jQuery的zepto(v1.1.3),在jsonp请求出现错误,比如加载js文档时头部返回401错误时,error函数会执行,但是该函数的jqXHR参数也同样不是正宗的jqXHR类型,甚至不能通过它获取响应的头部信息,在这种情况下,我们只是被告知某个环节出错了,却并不知道具体的错误信息。类似响应头承载有用信息的场景,博主不建议使用jsonp,可以说,使用jsonp的一个前提是:除了网络异常等非业务异常外,所有业务异常(概括地说,乃是从服务器接收请求到返回响应这段时间内抛出的所有异常)都需要以请求结果的形式直接返回给客户端,便于客户端回调分析。
Спасибо за чтение, надеюсь, это поможет вам, спасибо за поддержку нашего сайта!
Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему автору, контент предоставлен пользователями Интернета, сайт не имеет права собственности, не был отредактирован вручную, и не несет ответственности за соответствующие юридические последствия. Если вы обнаружите контент,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (во время отправки письма замените # на @) для подачи жалобы,并提供相关证据. При подтверждении факта нарушения авторских прав сайт немедленно удалят涉嫌侵权的内容。