search
HomeWeb Front-endJS TutorialCross-domain methods in js
Cross-domain methods in jsDec 09, 2017 pm 04:58 PM
javascriptmethod

When making oneday-music-player, I need to use ajax to send a request to Baidu Music's api, and then XMLHttpRequest cannot load 'http://....' . No 'Access-Control-Allow' appears. -Origin' header is present on the request resource. Origin 'http://....' is therefore not allowed access. After searching, it was found that it was a cross-domain problem caused by the same origin policy, so learn about Cross-domain knowledge points.

Same Origin Policy

The Same Origin Policy restricts documents or scripts loaded from one source from interacting with documents or scripts from another source. method is an important security mechanism for isolating potentially malicious files.

When two pages have the same protocol, port (if specified) and domain name, they can be said to have the same origin.

The following table is relative to <span style="font-size: 14px;">http://store.company.com/dir/page.html</span> Example of same-origin detection:

FailedDifferent ports (81 and 80)FailedDifferent domain names (

If it is not from the same origin, three behaviors will be restricted:

  • ##Cookie, LocalStorage and IndexDB cannot be read<span style="font-size: 14px;"></span>

  • DOM cannot be obtained<span style="font-size: 14px;"></span>

  • AJAX request cannot be sent<span style="font-size: 14px;"></span>

Avoid the same-origin policy (cross-domain)<span style="font-size: 14px;"></span>

Cookie<span style="font-size: 14px;"></span>

document.domain<span style="font-size: 14px;"></span>

Cookie is a small piece of information written by the server to the browser, which can only be shared by web pages of the same hospital. However, the first-level domain names of the two web pages are the same, but the second-level domain names are different. The browser allows sharing of cookies through <span style="font-size: 14px;"></span>document.domain<span style="font-size: 14px;"></span><span style="font-size: 14px;"></span>

For example, suppose a script in the document executes the following statement at <span style="font-size: 14px;"></span>http://store.company.com/dir/page.html<span style="font-size: 14px;"></span> :<span style="font-size: 14px;"></span>

<span style="font-size: 14px;">document.domain = "company.com"<br></span>

At this time,<span style="font-size: 14px;"></span>http://news.company.com/dir/other.html<span style="font-size: 14px;"></span> and<span style="font-size: 14px;"></span>http://store.company.com/dir/other.html<span style="font-size: 14px;"></span>
can be passed<span style="font-size: 14px;"></span>document .cookie<span style="font-size: 14px;"></span> to set or get cookies, that is, shared cookies. <span style="font-size: 14px;"></span>

But this method applies to Cookie and iframe windows, LocalStorage and IndexDB cannot circumvent the same origin policy through this method. <span style="font-size: 14px;"></span>

iframe<span style="font-size: 14px;"></span>

If two web pages have different sources, they cannot get each other’s DOM. A typical example is <span style="font-size: 14px;"></span> If the iframe<span style="font-size: 14px;"></span> window and the window opened by the <span style="font-size: 14px;"></span>window.open<span style="font-size: 14px;"></span> method are not from the same source as the parent window, it will Report an error. <span style="font-size: 14px;"></span>

At this time, if the first-level domain name of the two windows is the same, but the second-level domain name is different, then set <span style="font-size: 14px;"></span>document.domain<span style="font-size: 14px;"></span>Attribute, you can circumvent the same-origin policy. <span style="font-size: 14px;"></span>

For websites with completely different origins, there are currently three methods to solve the communication problem between cross-domain windows. <span style="font-size: 14px;"></span>

  • fragment identifier<span style="font-size: 14px;"></span>

  • window.name<span style="font-size: 14px;"></span>

  • Cross-document messaging API<span style="font-size: 14px;"></span>

Fragment identifier<span style="font-size: 14px;"></span>

The fragment identifier refers to the part after # in the URL, that is, <span style="font-size: 14px;"></span>http://store.company.com/dir/other.html# fragment<span style="font-size: 14px;"></span><span style="font-size: 14px;"></span>#fragment<span style="font-size: 14px;"></span>(location.hash), if only the fragment identifier is changed, the page will not be refreshed. <span style="font-size: 14px;"></span>

The parent window can write information to the fragment identifier of the child window, and the child window listens to the <span style="font-size: 14px;"></span>hashchange<span style="font-size: 14px;"></span> event Get notified. <span style="font-size: 14px;"></span>

window.name<span style="font-size: 14px;"></span>

Each iframe has a window that wraps it. This window is a child window of the top window, so naturally <span style="font-size: 14px;"></span>window.name<span style="font-size: 14px;"></span> attribute refers to the name of the current window. The biggest feature of this attribute is that, regardless of whether it has the same source or not, as long as the window is in the same window, All pages within have read and write permissions for window.name. <span style="font-size: 14px;"></span>

The value of window.name can only be in the form of a string. The maximum capacity of this string can be about 2M or even larger, depending on different browsers. <span style="font-size: 14px;"></span>

例如,想要在<span style="font-size: 14px;">http://example/a.html</span>中获取<span style="font-size: 14px;">http://company.com/data.html</span>中的数据,可以在a.html中使用一个隐藏的iframe,将iframe的src首先设置为<span style="font-size: 14px;">http://company.com/data.html</span>,将其window.name设置为所需的数据内容,随后再将这个iframe的src设置为跟a.html页面同一个域的一个页面,不然a.html获取不到该iframe的window.name

<span style="font-size: 14px;">window.postMessage</span>

这是html5中新引入的一个API,可以使用它向其它的window对象发送消息,无论这个window对象属于同源还是不同源。

例如,父窗口<span style="font-size: 14px;">http://example/a.html</span>向子窗口<span style="font-size: 14px;">http://company.com/data.html</span>发送消息:

<span style="font-size: 14px;">var newWin = window.open('http://company.com/data.html', 'title')<br>newWin.postMessage('Hello World!'. 'http://company.com/data.html')<br></span>

<span style="font-size: 14px;">window.postMessage</span>方法的第一个参数是具体的信息内容,第二个参数是接收消息的窗口的源,即<span style="font-size: 14px;">协议</span>+<span style="font-size: 14px;">端口</span>+<span style="font-size: 14px;">域名</span>,也可以设置为<span style="font-size: 14px;">*</span>,表示不限制域名。

子窗口向父窗口发送消息的写法类似:

<span style="font-size: 14px;">window.opener.postMessage('Nice to see you', 'http://example/a.html')<br></span>

子窗口和父窗口都可以通过<span style="font-size: 14px;">message</span>时间,监听对方的消息。

<span style="font-size: 14px;">window.addEventListener('message', function(e) {<br>    // ...<br>}, false)<br></span>

<span style="font-size: 14px;">message</span>事件的事件对象<span style="font-size: 14px;">event</span>有以下三个属性:

  • event.source: 发送消息的窗口

  • event.origin: 消息发向的网址(可以限制目标网址)

  • event.data: 消息内容

通过<span style="font-size: 14px;">window.postMessage</span>,也可以读写其他窗口的<span style="font-size: 14px;">localStorage</span>

AJAX

同源策略规定,AJAX请求只能发给同源的网址,否则就报错,但是有三种方法可以规避这个限定:

  • JSONP

  • WebSocket

  • CORS

JSONP

JSONP是服务器与客户端跨源通信的常用方法。基本思想是利用<span style="font-size: 14px;"><script></script></span>请求脚本能够跨域访问的特性,先定义了一个回调方法,然后将其作为url参数的一部分发送到服务端,服务端通过字符串拼接的方式将数据包裹在回调方法中,再返回回来。

<span style="font-size: 14px;">// 网页动态插入`<script>`元素<br/>function addScriptTag(src) {<br/>    var script = document.createElement("script")<br/>    script.setAttribute("type", "text/javascript")<br/>    srcipt.src = src<br/>    document.body.appendChild(script)<br/>}<br/><br/>window.onload = function() {<br/>    addScriptTag(&#39;http://example.com/ip?callback=foo&#39;)<br/>}<br/><br/>function foo(data) {<br/>    // ...<br/>}<br/></script></span>

WebSocket

WebSocket是一种通信协议,使用<span style="font-size: 14px;">ws://</span>(非加密)和<span style="font-size: 14px;">wss://</span>(加密)作为协议前缀。该协议不实行同源政策,只要服务支持,就可以通过它进行跨源通信。

浏览器发出的WebSocket请求的头信息中含有<span style="font-size: 14px;">Origin</span>字段,表示该请求的请求源,即发自哪个域名。(加入白名单)

CORS

跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种使用额外的HTTP头来使一个用户代理从一个不同于当前站点(域)的服务器获取指定的资源的机制。用户代理使用跨域HTTP请求来获取与当前文档不同域、不用协议或端口的资源。

出于安全考虑,浏览器会限制从脚本内发起的跨域HTTP请求。而跨域资源共享(CORS)机制允许web应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在API容器中(例如<span style="font-size: 14px;">XMLHttpRequest</span><span style="font-size: 14px;">Fetch</span>)使用CORS,以降低跨域HTTP请求所带来的风险。

跨域资源共享标准允许在下列场景中使用跨域HTTP请求:

  • 由XMLHttpRequest或Fetch发起的跨域HTTP请求;

  • web字体(CSS中通过<span style="font-size: 14px;">@font-face</span>使用跨域字体资源),因此,网站就可以发布TrueType字体资源,并只允许已授权网站进行跨站调用;

  • WebGL贴图;

  • 使用drawImage将Images/video画面绘制到canvas;

  • 样式表(使用CSSOM);

  • Scripts(未处理的异常)。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)

只要同时满足以下两大条件,就属于简单请求:

1 请求方法是以下三种方法之一:

<span style="font-size: 14px;">- HEAD<br>- GET<br>- POST<br></span>

2 HTTP的头信息不超出以下几种字段:

<span style="font-size: 14px;">- Accept<br>- Accept-Language<br>- Content-Language<br>- Last-Event-ID<br>- Content-Type:(只限三个值:application/x-www-form-urlencoded、multipart/from-data、text/plain)<br></span>

只要不同时满足上面两个条件,就属于非简单请求

简单请求

对于简单请求,浏览器会在请求头部增加一个<span style="font-size: 14px;">Origin</span>字段。这个字段用来说明本次请求来自哪个源(协议+域名+端口)。服务器根据这个值决定是否同意这次请求。

如果<span style="font-size: 14px;">Origin</span>指定的源不在许可范围内,服务器会返回一个正常的HTTP回应。而这个回应的头信息不包含<span style="font-size: 14px;">Access-Control-Allow-Origin</span>字段,从而会抛出错误被<span style="font-size: 14px;">XMLHttpRequest</span><span style="font-size: 14px;">onerror</span>函数捕获,(回应的状态码有可能是200)。

如果<span style="font-size: 14px;">Origin</span>指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段

<span style="font-size: 14px;">Access-Control-Allow-Origin: ...<br>Access-Control-Allow-Credentials: true<br>Access-Control-Expose-Headers: callback<br>Content-Type: text/html; charset=utf-8<br></span>
  • <span style="font-size: 14px;">Access-Control-Allow-Origin</span>: 必须。值要么是请求时<span style="font-size: 14px;">Origin</span>的值,要么是'*'

  • <span style="font-size: 14px;">Access-Control-Allow-Credentials</span>: 可选。布尔值,决定是否允许发送Cookie,不需要则删除该字段。

  • <span style="font-size: 14px;">Access-Control-Expose-Headers</span>: 可选。CORS请求时,<span style="font-size: 14px;">XMLHttpRequest</span>对象的 <span style="font-size: 14px;">getResponseHeader()</span>方法只能拿到6个基本字段:<span style="font-size: 14px;">Cache-Control</span><span style="font-size: 14px;">Content-Language</span><span style="font-size: 14px;">Content-Type</span><span style="font-size: 14px;">Expires</span><span style="font-size: 14px;">Last-Modified</span><span style="font-size: 14px;">Pragma</span>。如果想拿到其他字段,就需要在<span style="font-size: 14px;">Access-Control-Expose-Header</span>里面指定。上面的例子指定为callback,则可以使用<span style="font-size: 14px;">getResponseHeader(callback)</span>获取callback字段的值。

CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发送到服务器,一方面要服务器同意,指定<span style="font-size: 14px;">Access-Control-Allow-Credentials</span>字段,另一方面,开发者需要在AJAX请求中设置<span style="font-size: 14px;">withCredentials</span>属性:

<span style="font-size: 14px;">var xhr = new XMLHttpRequest()<br>xhr.withCredentials = true<br></span>

否则,即使服务器同意发送Cookie,浏览器也不会发送。

需要注意的是,如果要发送Cookie,<span style="font-size: 14px;">Access-Control-Allow-Origin</span>就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源策略,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且跨域的原网页中的<span style="font-size: 14px;">document.cookie</span>操作也无法获取嗷服务器域名下的Cookie。

非简单请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是<span style="font-size: 14px;">PUT</span><span style="font-size: 14px;">DELETE</span>,或者<span style="font-size: 14px;">Content-Type</span>字段的类型是<span style="font-size: 14px;">application/json</span>

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为“预检”请求。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP操作和头信息字段。只有得到肯定答复,浏览器才会发出正式的<span style="font-size: 14px;">XMLHttpRequest</span>请求,否则就报错。

“预检”请求用请求方法是<span style="font-size: 14px;">OPTIONS</span>,表示这个请求是用来询问的。头信息里面,关键字段是<span style="font-size: 14px;">Origin</span>,表示请求来自哪个源。

还有以下两个特殊字段:

  • <span style="font-size: 14px;">Access-Control-Request-Method</span>: 必须。列出非简单请求的请求类型

  • <span style="font-size: 14px;">Access-Control-Request-Headers</span>: 非简单请求额外携带的头信息字段。

服务器返回的响应:

<span style="font-size: 14px;">Access-Control-Allow-Methods: ...<br>Access-Control-Expose-Headers: callback<br>Access-Control-Allow-Credentials: true<br>Access-Control-Max-Age: 1728000<br></span>
  • Access-Control-Allow-Methods: 必须。逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。为了避免多次“预检”行为。

  • Access-Control-Expose-Headers: If the browser request includes <span style="font-size: 14px;">Access-Control-Request-Headers</span> field, the <span style="font-size: 14px;">Access-Control-Allow-Headers</span> field is required. It is also a comma-separated string indicating all header fields supported by the server, not limited to the fields requested by the browser in "preflight".

  • Access-Control-Allow-Credentials: has the same meaning as a simple request.

  • Access-Control-Max-Age: The validity period of this preflight request.

Comparison of CORS and JSONP

CORS has the same purpose as JSONP, but is more powerful than JSONP.

JSONP only supports <span style="font-size: 14px;">GET</span> requests, CORS supports all types of HTTP requests. The advantage of JSONP is that it supports older browsers and can request data from websites that do not support CORS.

Related recommendations:

Steps to implement lazy loading and cross-domain implementation using Js

How to understand Js cross-domain

Detailed explanation of how to enable laravel's cross-domain function

url Result Reason
##http://store.company.com/dir2/other.html<span style="font-size: 14px;"></span> Success<span style="font-size: 14px;"></span>
http://store.company.com/dir/inner/other.html <span style="font-size: 14px;"></span> Success<span style="font-size: 14px;"></span>
https://store.company.com/secure.html <span style="font-size: 14px;"></span> Failed<span style="font-size: 14px;"></span> Different protocols (<span style="font-size: 14px;"></span>https<span style="font-size: 14px;"></span> and<span style="font-size: 14px;"></span>http<span style="font-size: 14px;"></span>)<span style="font-size: 14px;"></span>
##http://store.company. com:81/dir/etc.html<span style="font-size: 14px;"></span> <span style="font-size: 14px;"></span>
http://news.company.com/dir/other.html<span style="font-size: 14px;"></span> <span style="font-size: 14px;"></span> <span style="font-size: 14px;"></span>news<span style="font-size: 14px;"></span> and <span style="font-size: 14px;"></span>store<span style="font-size: 14px;"></span> )<span style="font-size: 14px;"></span>

The above is the detailed content of Cross-domain methods in js. For more information, please follow other related articles on the PHP Chinese website!

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
es6数组怎么去掉重复并且重新排序es6数组怎么去掉重复并且重新排序May 05, 2022 pm 07:08 PM

去掉重复并排序的方法:1、使用“Array.from(new Set(arr))”或者“[…new Set(arr)]”语句,去掉数组中的重复元素,返回去重后的新数组;2、利用sort()对去重数组进行排序,语法“去重数组.sort()”。

JavaScript的Symbol类型、隐藏属性及全局注册表详解JavaScript的Symbol类型、隐藏属性及全局注册表详解Jun 02, 2022 am 11:50 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于Symbol类型、隐藏属性及全局注册表的相关问题,包括了Symbol类型的描述、Symbol不会隐式转字符串等问题,下面一起来看一下,希望对大家有帮助。

原来利用纯CSS也能实现文字轮播与图片轮播!原来利用纯CSS也能实现文字轮播与图片轮播!Jun 10, 2022 pm 01:00 PM

怎么制作文字轮播与图片轮播?大家第一想到的是不是利用js,其实利用纯CSS也能实现文字轮播与图片轮播,下面来看看实现方法,希望对大家有所帮助!

JavaScript对象的构造函数和new操作符(实例详解)JavaScript对象的构造函数和new操作符(实例详解)May 10, 2022 pm 06:16 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于对象的构造函数和new操作符,构造函数是所有对象的成员方法中,最早被调用的那个,下面一起来看一下吧,希望对大家有帮助。

JavaScript面向对象详细解析之属性描述符JavaScript面向对象详细解析之属性描述符May 27, 2022 pm 05:29 PM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于面向对象的相关问题,包括了属性描述符、数据描述符、存取描述符等等内容,下面一起来看一下,希望对大家有帮助。

javascript怎么移除元素点击事件javascript怎么移除元素点击事件Apr 11, 2022 pm 04:51 PM

方法:1、利用“点击元素对象.unbind("click");”方法,该方法可以移除被选元素的事件处理程序;2、利用“点击元素对象.off("click");”方法,该方法可以移除通过on()方法添加的事件处理程序。

整理总结JavaScript常见的BOM操作整理总结JavaScript常见的BOM操作Jun 01, 2022 am 11:43 AM

本篇文章给大家带来了关于JavaScript的相关知识,其中主要介绍了关于BOM操作的相关问题,包括了window对象的常见事件、JavaScript执行机制等等相关内容,下面一起来看一下,希望对大家有帮助。

foreach是es6里的吗foreach是es6里的吗May 05, 2022 pm 05:59 PM

foreach不是es6的方法。foreach是es3中一个遍历数组的方法,可以调用数组的每个元素,并将元素传给回调函数进行处理,语法“array.forEach(function(当前元素,索引,数组){...})”;该方法不处理空数组。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
1 months agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

mPDF

mPDF

mPDF is a PHP library that can generate PDF files from UTF-8 encoded HTML. The original author, Ian Back, wrote mPDF to output PDF files "on the fly" from his website and handle different languages. It is slower than original scripts like HTML2FPDF and produces larger files when using Unicode fonts, but supports CSS styles etc. and has a lot of enhancements. Supports almost all languages, including RTL (Arabic and Hebrew) and CJK (Chinese, Japanese and Korean). Supports nested block-level elements (such as P, DIV),

SublimeText3 Linux new version

SublimeText3 Linux new version

SublimeText3 Linux latest version

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

PhpStorm Mac version

PhpStorm Mac version

The latest (2018.2.1) professional PHP integrated development tool

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools