不要再问我跨域的问题了 https://segmentfault.com/a/1190000015597029?utm_source=tag-newest
跨域问题来源于JavaScript的同源策略,即只有 协议+主机名+端口号
(如存在)相同,则允许相互访问。也就是说JavaScript只能访问和操作自己域下的资源,不能访问和操作其他域下的资源。跨域问题是针对JS和ajax的,html本身没有跨域问题,比如a标签、script标签、甚至form标签(可以直接跨域发送数据并接收数据)等
同源策略
URL由协议、域名、端口和路径组成,如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。
下表给出了相对http://store.company.com/dir/page.html
同源检测的示例:
URL | 结果 | 原因 |
---|---|---|
http://store.company.com/dir2/other.html | 成功 | 只有路径不同 |
http://store.company.com/dir/inner/another.html | 成功 | 只有路径不同 |
https://store.company.com/secure.html | 失败 | 不同协议 ( https和http ) |
http://store.company.com:81/dir/etc.html | 失败 | 不同端口 ( http:// 80是默认的) |
http://news.company.com/dir/other.html | 失败 | 不同域名 ( news和store ) |
同源策略限制了从同一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。
浏览器采用同源策略,这是一个安全功能,禁止页面加载或执行与自身来源不同的域的任何脚本。
Ajax关于readyState(状态值)和status(状态码)的研究
https://www.cnblogs.com/liu-fei-fei/p/5618782.html
HTTP访问控制(CORS)
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
介绍了cors的使用场景,什么是简单请求,预检请求,HTTP 响应首部字段,HTTP 请求首部字段
简单请求:
- 请求方法只能为GET、HEAD、POST
- 请求首部中无自定义首部字段
- Content-Type必须为text/plain、multipart/form-data、application/x-www-form-urlencoded
符合以上条件的为简单请求,否则为非简单请求
HTTP 请求首部字段:
Origin 源站 URI。它不包含任何路径信息,只是服务器名称。
Access-Control-Request-Method 首部字段用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器。
Access-Control-Request-Headers首部字段用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器。
HTTP 响应首部字段:
Access-Control-Allow-Origin指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为‘ * ’,表示允许来自所有域的请求。
Access-Control-Allow-Credentials指定了当浏览器的credentials
设置为true时是否允许浏览器读取response的内容。当用在对preflight预检测请求的响应中时,它指定了实际的请求是否可以使用credentials
。请注意:简单 GET 请求不会被预检;如果对此类请求的响应中不包含该字段,这个响应将被忽略掉,并且浏览器也不会将相应内容返回给网页。
Access-Control-Max-Age 指定了请求的结果能够被缓存多久
Access-Control-Allow-Headers 首部字段用于预检请求的响应。其指明了实际请求中允许携带的首部字段。
Access-Control-Allow-Methods首部字段用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。
出现415错误的解决方法:
1. 前端看ajax请求的contentType是否与后端一致
2. 看发送的数据格式是否正确。
下例为后端所需数据为json格式,contentType为application/json的ajax请求。
function getAddDirResponse(data) {
$.ajax({
url:'/algor/api/datadirs',
type:'POST',
contentType: 'application/json; charset=UTF-8',
async:false,
dataType:'json',
data:JSON.stringify(data),
success: function (response) {
console.log(response);
}
})
}
四种常见的 POST 提交数据方式
(application/x-www-form-urlencoded,multipart/form-data,application/json,text/xml)https://blog.csdn.net/xiao__jia__jia/article/details/79357274 (这个讲的很好)
我们知道,HTTP 协议是以 ASCII 码传输,建立在 TCP/IP 协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。类似于下面这样:
<method> <request-URL> <version>
<headers>
<entity-body>
协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以。
但是,数据发送出去,还要服务端解析成功才有意义。一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。下面就正式开始介绍它们。
- 1. application/x-www-form-urlencoded 窗体数据被编码为名称/值对。
默认情况下contentType 是 application/x-www-form-urlencoded,这应该是最常见的 POST 提交数据的方式了,浏览器的原生 form 表单,如果不设置 enctype 属性,那么最终就会以 application/x-www-form-urlencoded 方式提交数据。浏览器把form数据转换成一个字串(name1=value1&name2=value2…),然后把这个字串append到url后面,用?分割,加载这个新的url,key 和 val 都进行了 URL 转码。
- 2. application/json 序列化后的 JSON 字符串
现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。JSON 格式支持比键值对复杂得多的结构化数据,而且灵活方便。
- 3. multipart/form-data 文件上传时用
我们使用表单上传文件时,必须让 form 的 enctyped 等于这个值。窗体数据被编码为一条消息,页上的每个控件对应消息中的一个部分。浏览器会把整个表单以控件为单位分割,并为每个部分加上Content-Disposition(form-data或者file),Content-Type(默认为text/plain),name(控件name)等信息,并加上分割符(boundary)。
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryrGKCBY7qhFd3TrwA
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="text"
title
------WebKitFormBoundaryrGKCBY7qhFd3TrwA
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
PNG ... content of chrome.png ...
------WebKitFormBoundaryrGKCBY7qhFd3TrwA--
(上面的例子:首先生成了一个 boundary 用于分割不同的字段,为了避免与正文内容重复,boundary 很长很复杂。然后 Content-Type 里指明了数据是以 mutipart/form-data 来编码,本次请求的 boundary 是什么内容。消息主体里按照字段个数又分为多个结构类似的部分,每部分都是以 –boundary 开始,紧接着内容描述信息,然后是回车,最后是字段具体内容(文本或二进制)。如果传输的是文件,还要包含文件名和文件类型信息。消息主体最后以 –boundary– 标示结束。)
- 4. text/xml 文本方式的html
CORS场景
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS