用node来实现一个简单的HTTP服务
在终端启动服务
浏览器端
关于HTTP的header的一些功能
什么是HTTP的客户端:最简单最常用的HTTP客户端就是浏览器,浏览器不仅发送HTTP请求和返回内容,还帮我们处理了返回的内容。
这个就是HTTP的首行信息,并不属于headers里面的内容,
再看response
response其实是一堆html代码。返回的这些html如何变成我们看到的页面呢?浏览器又做了一些工作。
用curl来请求
返回的内容很少,浏览器会识别这些标签。
可以用curl -v 来更详细的展示请求和返回的header和general相关的一些东西。
用curl不会像浏览器一样去渲染。
浏览器同域的限制
两个端口不一样的server
启动这两个服务,这时候我们是用8888端口去请求8889,浏览器中观察下
确实有了html的结构
但是
因为8889端口没有设置允许跨域的header,所以出现了跨域问题。
我们可以在server2.js里面设置
重启一下服务,
再到浏览器中,就没有报错了,并且成功请求了8889
不管我们有没有返回header,浏览器都会向我们这个服务发送这个请求。浏览器在发送这个请求的时候,并不知道这个服务是不是跨域。
请求已经发送了,内容也已经返回了,只是浏览器在解析了这个返回的内容之后,它发现这个是不允许的,就帮我们拦截了,这其实是浏览器提供的一个功能。
如果在curl里面,随便怎么发送,都是没有跨域的概念的。
跨域的方法:jsonp
这样子请求依旧是成功的,浏览器允许向link、img、script标签,在标签上src加载一些内容的时候,是允许跨域的。并不在乎服务器是否设置了跨域的头。
jsonp实现的原理就是在script标签里面加载了一个链接,这个链接访问了服务器的某一个请求,并且返回了内容。因为服务器返回的内容是可控的,所以我们可以在服务器的返回内容里面写script标签里面的代码,是一段可执行的js代码。然后调用jsonp在发起请求之前,给我们设置的一些内容。
跨域的头的设置
如果把Access-Control-Allow-Origin设置为*,是不安全的,因为任何人都可以访问,可以把*设置为某一个特定的域名,比如设置为http://xxx.com当然不会有这个域名来请求这个服务。我们可以把头设置为127.0.0.1,依然可以实现跨域。这个头只能设置一个值,不能设置为多个值。
html文件我们用fetch
server2.js文件不变
我们写的X-Test-Cors在跨域请求的时候是不被允许的。
其他限制:
在跨域的时候允许的方法:GET HEAD POST ,其他的方法默认不允许,预请求会验证。这三个方法不需要预请求。
允许的Content-Type:text/plain multipart/form-data application/x-www-form-urlencoded,其他的值也要通过预请求之后才能进行发送。
其他限制:请求头限制(比如上文的请求头),XMLHttpRequestUpload对象均没有注册任何事件监听器,请求中没有使用ReadableStream对象。
CORS的预请求
浏览器根据什么判断这个返回的内容是不是允许的呢?就是header。
如果我们要允许我们自定义的头在请求里面发送,我们需要返回一个新的头来告诉浏览器,这个操作是允许的。
这个时候浏览器是请求成功的。
但是比之前多出一个请求,就是预请求。method为OPTIONS.
类似的,我们也可以通过设置,来使用除了GET HEAD POST这三个方法以外的方法。
还可以设置一下,'Access-Control-Max-Age': '1000' 在这个请求下面允许以这种方式实现跨域的请求的最长时间,比如,1000秒之内不需要再发送预请求来验证了,发正式请求就可以了。