您的位置:首页 > Web前端

跨域请求 fetch 实现

2017-06-07 13:27 176 查看
reference : [1].https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

1.CORS 的分类

分为两大类:简单的请求;带有preflight预请求的CORS。两类请求的区分标准如下:

简单请求

某些请求不会触发 CORS 预检请求。本文称这样的请求为“简单请求”。若请求满足所有下述条件,则该请求可视为“简单请求”:

1. 使用下列方法之一: GET HEAD POST
2. Fetch 规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为: Accept Accept-Language Content-Language Content-Type (需要注意额外的限制) DPR Downlink Save-Data Viewport-Width Width
3. Content-Type 的值属于下列之一: application/x-www-form-urlencoded multipart/form-data text/plain


剩下的都是,带有preflight的CORS。带有preflight的CORS ,浏览器会先发出一个 OPTIONS请求,服务器在响应里写入是否允许该域名发起访问,在response的header里面加入了Access-Control-Allow-Origin,Access-Contral-Allow-Methods,Access-Contraol-Allow-Headers,Access-Control-Max-Age,这几个字段(各个字段详细意义参见reference 1),



2.进行带有身份凭证的CORS 请求

默认情况下的跨域请求都是不会把cookie发送给服务器的,在需要发送的情况下,如果是xhr,那么需要设置
xhr.withCredentials = true
,如果是采用fetch获取的话,那么需要在request里面设置
credentials:'include',
但是如果服务器在预请求的时候没返回
Access-Control-Allow-Crenditials:true
的话,那么在实际请求的时候,cookie是不会被发送给服务器端的,要特别注意对于简单的get请求,不会有预请求的过程,那么在实际请求的时候,如果服务器没有返回
Access-Control-Allow-Crenditials:true
的话 那么响应结果浏览器也不会交给请求者


3.fetch的配置

import {
baseUrl
} from '../../config/env.config.js'
import {formDataToJson} from '../../utils/form.js';
import * as es6Promise from 'es6-promise'
import 'isomorphic-fetch'

es6Promise.polyfill();

export default async(type = 'GET', url = '', data = {}) => {

type = type.toUpperCase();
url = baseUrl + url;

if (type == 'GET') {
let dataStr = ''; //数据拼接字符串
Object.keys(data).forEach(key => {
dataStr += key + '=' + data[key] + '&';
})

if (dataStr !== '') {
dataStr = dataStr.substr(0, dataStr.lastIndexOf('&'));
url = url + '?' + dataStr;
}
}
if (type == 'DELETE') {
url = url + "/" + data.id;
}

let requestConfig = {
credentials: 'include',
method: type,
headers: {
'Accept': 'application/json',
'Content-Type' : 'application/json'
},
mode: "cors",
cache: "force-cache"
}

if (type == 'POST') {
if (window.FormData && data instanceof FormData) {
Object.defineProperty(requestConfig, 'body', {
value: formDataToJson(data)
})
} else {
Object.defineProperty(requestConfig, 'body', {
value: JSON.stringify(data)
})
}

}

try {
var response = await fetch(url, requestConfig);
var responseJson = await response.json();
} catch (error) {
throw new Error(error)
}
return responseJson

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  cors fetch