先后端分离来讲,跨域请求是咱们第一个须要解决的问题。下面是我在开发中总结出来的一些经验。
javascript
开发中,不少时候会出现Options请求(CORS预检请求),可是有的时候又不会出现。某些请求不会触发 CORS 预检请求,这样的请求被称为简单请求,其余的请求被称为非简单请求。首先咱们来区分简单请求和非简单请求。css
浏览器将CORS请求分红两类:简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时知足如下两大条件,就属于简单请求。html
HEAD、GET、POST前端
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain凡是不一样时知足上面两个条件,就属于非简单请求
。浏览器对这两种请求的处理,是不同的。java
如今咱们知道咱们哪些请求是简单请求哪些是非简单请求,上面有提到HTTP头部和CORS跨域请求,CORS全称Cross-origin resource sharing,也就是跨域资源共享,浏览器出于安全角度考虑限制跨域HTTP请求,这就是同源策略,因此后端须要设置请求头部才能容许跨域。node
是逗号分隔的一个字符串,代表服务器容许的跨域请求的方法。jquery
是一个逗号分隔的字符串,代表服务器支持的全部头信息字段,不限于浏览器在”预检”中请求的字段。ajax
该字段表示是否能够将对请求的响应暴露给页面,通常来讲是cookie。Credentials必须在先后端都被配置才能使带credentials的CORS请求成功。jQuery能够经过设置xhrFields: {withCredentials:true}
,promise能够经过设置credentials: 'include'
。json
用来指定本次预检请求的有效期,单位为秒。segmentfault
表示资源是否被容许与给定的origin共享。
响应首部 Access-Control-Expose-Headers 列出了哪些首部能够做为响应的一部分暴露给外部。默认状况下,只有六种 simple response headers (简单响应首部)能够暴露给外部:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。若是想要让客户端能够访问到其余的首部信息,能够将它们在 Access-Control-Expose-Headers 里面列出来。
请求首部 Access-Control-Request-Headers 出现于 preflight request (预检请求)中,用于通知服务器在真正的请求中会采用哪些请求首部。
请求首部 Access-Control-Request-Method 出现于 preflight request (预检请求)中,用于通知服务器在真正的请求中会采用哪一种 HTTP 方法。由于预检请求所使用的方法老是 OPTIONS ,与实际请求所使用的方法不同,因此这个首部是必要的。
若是须要发送cookie,先后端都被配置,前端须要设置jQuery能够经过设置xhrFields: {withCredentials:true}
,promise能够经过设置credentials: 'include'
。
服务器端须要设置res.setHeader('Access-Control-Allow-Credentials', 'true');
不然浏览器就会报错:
须要注意的是,若是要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。
同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其余域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也没法读取服务器域名下的Cookie。
这时候浏览器会报错
//解析cookie的函数
function parseCookies (request) {
let list = {},
rc = request.headers.cookie;
rc && rc.split(';').forEach(function( cookie ) {
let parts = cookie.split('=');
list[parts.shift().trim()] = decodeURI(parts.join('='));
});
return list;
}
http.createServer(function (request, response) {
//读取cookie
var cookies = parseCookies(request);
//写入cookie
response.writeHead(200, {
'Set-Cookie': 'mycookie=test',
'Content-Type': 'text/plain'
});
response.end('Hello World\n');}).listen(8124);
})
复制代码
对接后端的接口的时候,Content-Type的值是决定后端那边怎么去解析咱们的传参的。Content-type经常使用几个值:
1.text/html
2.text/plain
3.text/css
4.text/javascript
5.application/x-www-form-urlencoded
6.multipart/form-data
7.application/json
8.application/xml
前面几个都很好理解,都是html,css,javascript的文件类型,后面四个是POST的发包方式。
html中表单提交的默认格式,jquery ajax请求默认的content-type默认也是这种格式,而且jquery会把data:{foo1:”bar1”,foo2:”bar2”}数据转换成key1=value1&key2=value2,能够经过processData来关闭是否提早处理数据,数据格式是key1=value1&key2=value2形式。
下面是jquery作data预处理的代码,默认processData为true,因此若是data有值就会进入判断就会把json格式转化为key1=value1&key2=value2的格式
if ( s.data && ( s.processData || typeof s.data === "string" ) ) {
cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
// #9682: remove data so that it's not used in an eventual retry
delete s.data;
}复制代码
multipart/form-data用在发送文件的POST包。
这里Content-Type告诉咱们,发包是以multipart/form-data格式来传输,另外,还有boundary用于分割数据。
当文件太长,HTTP没法在一个包以内发送完毕,就须要分割数据,分割成一个一个chunk发送给服务端,
那么—用于区分数据快,然后面的数据sqe6Nhq4gtMfHLOY 就是标示区分包做用。
------WebKitFormBoundarysqe6Nhq4gtMfHLOY
Content-Disposition: form-data; name:"UserWxCode"
123
------WebKitFormBoundarysqe6Nhq4gtMfHLOY
Content-Disposition: form-data; name="CodeType"
Public
------WebKitFormBoundarysqe6Nhq4gtMfHLOY--复制代码
发送请求的时候须要JSON.stringify一下,HTTP通讯中并不存在所谓的json,而是将string转成json罢了,也就是,application/json能够将它理解为text/plain,普通字符串。
text/xml忽略xml文件头中的关于编码的设定(<?xml version=”1.0” encoding=”UTF-8”?>
),默认采用us-ascii编码。 application/xml会依照xml文件头中编码的设定。推荐使用application/xml
//fetch设置Headers,cookies
//方式1
let myHeaders = new Headers({
'Content-Type': 'application/json; charset=UTF-8',
'token': 123
});
//方式2
headers: {
'Content-Type': 'application/json; charset=UTF-8',
'token': 123
}
//发送cookies:
credentials: 'include'
//jquery ajax设置Headers,cookies
//设置header方式一
headers: {
UserName: 'zxplus',
EncryptKey: '1111'
},
//方式二
beforeSend: function(request) {
request.setRequestHeader("UserName", "zxplus");
},
//发送cookie
xhrFields: {
withCredentials:true //支持附带详细信息
},复制代码
https://stackoverflow.com/questions/3393854/get-and-set-a-single-cookie-with-node-js-http-serverhttp://www.ruanyifeng.com/blog/2016/04/cors.htmlhttps://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORShttps://segmentfault.com/a/1190000006039533http://www.cnblogs.com/caoshiqing/p/6825608.htmlhttp://homeway.me/2015/07/19/understand-http-about-content-type/