美文网首页
http中的跨域问题

http中的跨域问题

作者: 平凡的lily | 来源:发表于2018-08-27 18:08 被阅读0次

    浏览器存在同源策略,当schema、IP、port中任何一个不相同,浏览器就认为是跨域,就会忽略返回结果,并且在console中报错。浏览器会发送请求,并且接受请求,但是解析后发现是不满足条件,则。。。。如果客户端没有实现这个功能,那么就不存在跨域问题,比如自己实现的一个客户端。

    下面将通过一个简单的例子来阐述一些问题,知识点包括,http server端, ajax的原生实现,异步,跨域问题。一共包括三个文件,命名为server.js、server2.js、test.html。

    test.html server.js


    server2.js

    test.html中展示了一种简单形式的ajax的实现,其中的readyState和status的含义如下

    readyState:

    0-(未初始化)还没有调用send()方法。

    1-(载入)已经调用send()方法,正在发送请求。

    2-(载入完成)send()方法执行完成,已经接收到全部响应内容。

    3-(交互)正在解析响应内容。

    4-(完成)响应内容解析完成,可以在客户端调用了。

    status:

    2xx-表示成功处理。

    3xx-需要重定向,浏览器直接跳转。

    4xx-客户端请求错误,如404

    5xx-服务器端错误,比如代码有问题500,504服务端连接数据库超时。

    例子中8888端口通过xhr访问8887端口的内容,由于端口不一样存在跨域,则浏览器出现错误:

    但是在network中仍然收到了response,说明了跨域问题是因为浏览器的同源策略引起的,虽然可以收到response,浏览器却不准许用这个内容来渲染或者处理页面。

    下面将server2.js加上'Access-Control-Allow-Origin':'http://127.0.0.1:8888'或者'Access-Origin-Allow-Origin':'*',浏览器检查到这个头,则准许8888对8887跨域访问。'*'表示8887准许任何server对其访问。

    server2.js

    然而,是不是只要加上相应的跨域请求头,就可以解决所有服务间跨域之间的问题呢,其实并不是,浏览器还有一些其他的限制,现在将test.html改为下图所示,加上request header:

    test.html

    浏览器报错,如下:

    然我们看下network里面:

    可以看出,这里就一个OPTIONS的请求,可是我们在test.html中定义的method明明是GET。这是为什么呢,看console中报的错误,考虑跟我们加进去的request header有关,也就是xhr.setRequestHeader('X-Test-Core', '123')。

    再来看另外一个例子,此时我们把这个报错的的request header略去,将request method从GET改为PUT。

    test.html

    此时浏览器报错,如下:

    我们看下network中的情况:

    这个network中也不见我们在test.html中定义的PUT方法,却只看见了一个OPTIONS的方法。而console中也提示是Acess-Control-Methods的错误,考虑到本文一开始用GET方法的例子正确,可以猜测跟PUT methods有关。

    综上,我带着疑问去寻找答案,也就是,浏览器对于除了对跨域有基本的限制之外,还存在一些具体的限制。这些限制大多是通过request header来判定的,server端response header必须有对应的字段才能准许跨域请求,同时,浏览器通过CORS预请求对其进行验证。上面两个失败的例子,我通过修改server2.js中返回的header可以得到正确的结果,这里我不再一个个验证,而是一起解决。

    test.html server2.js

    总结,默认跨域允许方法:GET,HEAD,POST 

     默认允许Content-Type:text/plain  multipart/form-data  application/x-www-form-urlencoded   (form表单的3种数据类型)

    XMLHttpRequestUpload对象均没有注册任何事件监听器。

    请求中没有使用ReadableStream对象。

    其他限制:请求头的限制,具体见'https://fetch.spec.whatwg.org/#cors-safelisted-request-header'

    超出以上范围则需要在server端设置准许才行,同时浏览器会发送OPTIONS请求进行验证。

    然而,浏览器对html标签中存在的src href等属性并不会做跨域限制,因此实际工作中我们利用这个特性来实现跨域的需求。这种方法通常称为JSONP。下面以script标签中的src属性为例。

    test.html server2.js

    8888端口请求8887端口的数据,控制台没有报错,由于返回了callback('abc'),字符串'abc'作为参数传递到callback中,最后返回到test.html请求的的script标签的位置,由于callback函数在上面有定义,则执行callback函数,打印出'abc'。由以上过程看出,JSONP作为跨域的解决方式,需要后端更加紧密的配合,返回需要执行的代码。

    相关文章

      网友评论

          本文标题:http中的跨域问题

          本文链接:https://www.haomeiwen.com/subject/jcxjiftx.html