ajax跨域请求(cors实现),Web高级 Ajax和跨域CORS(示例代码)

Asynchronous JavaScript and XML

1. XMLHttpRequest

前端开发都知道,不多说。

var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function () {

if (xhr.readyState !== 4) return;

if (xhr.status >= 200 && xhr.status < 300) {

console.log(JSON.parse(xhr.responseText));

}

else {

// What to do when the request has failed

console.log(\'error\', xhr);

}

};

xhr.open(\'GET\', \'https://mysite.com/index\');

xhr.setRequestHeader(\'X-Token\', \'123456\');

xhr.send();

1.1 open方法

定义:open( Method, URL, Asynchronous, UserName, Password )

- Method:GET/POST/HEAD/PUT/DELETE/OPTIONS

- Asynchronous(defualt true)

1.2 setRequestHeader方法

定义:setRequestHeader( Name, Value )

注意,以X开头的为header为自定义头部

1.3 send方法

定义:send(body)

body可以是:document,Blob, BufferSource, FormData, URLSearchParams, ReadableStream等

2. Fetch

新一代旨在替换XHR的API方法。

fetch("https://mysite.com/index", {

method: "POST",

headers: {

"Content-Type": "application/x-www-form-urlencoded",

\'X-Token\': \'123456\'

},

body: "id=123"

}).then(function (response) {

if (response.ok) {

return response.json();

} else {

return Promise.reject({

status: response.status,

statusText: response.statusText

});

}

})

.then(function (data) {

console.log(\'success\', data);

})

.catch(function (error) {

console.log(\'error\', error);

});

2.1 fetch方法

定义:fetch(input, init)

input:URL或者Request对象

init:一个配置项对象,包括所有对请求的设置。可选的参数有:

method: 请求使用的方法,如 GET、POST。

headers: 请求的头信息,形式为 Headers 对象或 ByteString。

body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。

mode: 请求的模式,如 cors、 no-cors 或者 same-origin。

credentials: 请求的 credentials,如 omit、same-origin 或者 include。

cache: 请求的 cache 模式: default, no-store, reload, no-cache, force-cache, or only-if-cached.

2.2 回调

fetch返回一个promise,采用then的链式调用避免回调地狱问题。

2.3 返回值

3. XHR vs Fetch

Fetch返回值不是可读的形式,需要使用response.json()转换为可读形式

XHR的请求失败通过判断状态码,Fetch请求失败通过catch处理

Fetch默认不带cookie,XHR默认带cookie

Fetch在服务器返回 400,500 错误码时并不会reject而被当做成功处理进then,只有网络错误这些导致请求不能完成才会触发catch

Fetch没有abort和onTimeout,不能中途中断,XHR可以。

Cross-Origin Resource Sharing

CORS是一种机制,用来保护跨域数据传输的安全性和降低风险。

1. 常见的可以跨域请求的资源

XHR或Fetch发起的跨域HTTP请求

Web字体

CSS文件

Scripts文件

2. 跨域相关的Http首部

Access-Control-Request-Headers

(Preflight使用)客户端告诉服务器实际请求时使用的头部。

Access-Control-Request-Method

(Preflight使用)客户端告诉服务器实际请求时使用的方法。

Access-Control-Allow-Origin

服务端允许请求的源域

Access-Control-Allow-Credentials

服务端是否允许请求带cookie,设置为true时allow-origin不能为*

Access-Control-Allow-Headers

服务端允许的客户端请求的头部

Access-Control-Allow-Methods

服务端允许客户端请求的方法

Access-Control-Max-Age

preflight可以被缓存的时间

Cross-Origin-Resource-Policy

(fetch使用)具体查看https://fetch.spec.whatwg.org/#cross-origin-resource-policy-header

Origin

客户端请求从哪个域来

1. OPTIONS /resources/post-here/

2. HTTP/1.1

3. Host: bar.other

4. User-Agent: Mozilla/5.0 (Macintosh; U; 5.Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre

6. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

7. Accept-Language: en-us,en;q=0.5

8. Accept-Encoding: gzip,deflate

9. Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

10. Connection: keep-alive

11. Origin: http://foo.example

12. Access-Control-Request-Method: POST

13. Access-Control-Request-Headers: X-PINGOTHER, Content-Type

//响应

14. HTTP/1.1 200 OK

15. Date: Mon, 01 Dec 2008 01:15:39 GMT

16. Server: Apache/2.0.61 (Unix)

17. Access-Control-Allow-Origin: http://foo.example

18. Access-Control-Allow-Methods: POST, GET, OPTIONS

19. Access-Control-Allow-Headers: X-PINGOTHER, Content-Type

20. Access-Control-Max-Age: 86400

21. Vary: Accept-Encoding, Origin

22. Content-Encoding: gzip

23. Content-Length: 0

24. Keep-Alive: timeout=2, max=100

25. Connection: Keep-Alive

26. Content-Type: text/plain

3. 简单请求

跨域请求分为简单请求和预检请求,全部符合下列条件时为简单请求:

使用的方法为:GET/HEAD/POST

不得设置安全首页之外的首页:Accept,Accept-Language,Content-Language,Content-Type,DPR,Downlink,Save-Data,Viewport-Width,Width

Content-Type只能是以下值: text/plain, multipart/form-data, application/x-www-form-urlencoded

请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器

请求中没有使用 ReadableStream 对象

当使用普通请求时,如果服务器允许该源域跨域请求资源,则直接返回响应。如果服务器不允许跨域请求,则返回不正确的响应首部,则请求方不会收到任何数据。

c5ef1d66bc424313864e8755fd6f1eb6.jpg

4. 预检请求(preflight request)

除了简单请求的情况,其他的CORS请求都会有预检请求。

预检请求会先使用OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求,所以会进行2个回合的通信。

典型的会触发预检请求的跨域情景:请求JSON数据 或 带有自定义头部

如:

content-type:application/json

X-Audit-Token:X123456

498d04602fbf4a618e8ca7f97840c49a.jpg

JSONP

跨域请求的一种常见实现方式.

1. 优缺点

优点:

不受同源策略限制,可以向没有启用CORS的跨域服务端请求数据。

兼容性较强,所有浏览器都支持该技术。

缺点

只支持GET,不支持POST

请求失败时不会有HTTP状态码返回

安全性也是一个值得考虑的问题

2. 实现原理

Client端用JS动态生成一个script标签并添加到文档流中,如

function jsonpCallBack(data){

console.log(data.msg);

}

$(document).ready(function(){

$("body").append(\'\');

});

浏览器会使用GET方法请求ASite上的ServerJSONP.js并携带参数

服务端接收到该请求,并根据参数中的回调函数名动态生成返回的内容,如

jsonpCallBack({msg:"this is jsonp request!"});

浏览器获取到script标签请求的内容后会执行其中的代码

最终我们定义的jsonpCallBack函数会被调用,输出: "this is jsonp request!"

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值