正视跨域

217 阅读2分钟

前端开发中,跨域是是开发员们常遇到的问题,也是面试中被问到的问题中热度非常高的。面对跨域,我们要正视它,不慌不忙的分析解决它。

什么是跨域

跨域,是指同一个域下的文档或脚本试图去请求另一个域下的资源(这里跨域是广义的)。 那么什么又是广义的跨域和狭义的跨域呢?
广义的跨域:
1. 资源跳转: a标签的超链接、重定向、表单提交
2. 资源嵌入: link、script、img等dom标签
狭义的跨域: 是由浏览器同源策略限制的一类请求场景。而同源策略要求两个服务需要通信遵守同源策略:即同协议 、 同域名 、 同端口。同源 浏览器才会让你发出请求,如果不同源,就产生跨域问题。即:

基于Node的普通跨域请求

具体步骤如下:

  1. 前端设置
let requestHeaders = new Headers();
 requestHeaders.append('X-auth', 'dhyaun')
 requestHeaders.append('content-type', 'application/json')
 fetch('http://localhost:3000/api/getBook', {
   method: 'POST',
   data:{page: 1},
   headers:requestHeaders
 })
 .then(res => res.json())
 .then(data => {
   console.log(data)
 })

2.后端实例代码:

const http = require('http')
http.createServer((req, res) => {
console.log(req.url, req.method)
// 'Access-Control-Allow-Credentials': true 是否允许 cookie 传输
res.writeHead(200, {
 'content-type': 'application/json',
 'Access-Control-Allow-Origin': '*',
 'Access-Control-Allow-Headers': 'x-auth, content-type',
 'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS',
 'Access-Control-Allow-Credentials': true
})
res.end(JSON.stringify({
 bookName: 'php'
}))
})
.listen(3000,() => {
console.log('启动成功: http://localhost:3000')
})

jsonP的跨域

何为jsonP: jsonp的整个过程就类似于前端声明好一个函数, 后端返回执行函数。执行函数参数中携带所需的数据。此外,主要是因为link script img 不受同源策略的影响,可以使用这些标签实现跨域。


具体步骤如下:
1.前端设置 

<script>    function getBook(res) {      console.log('得到的结果 :', res)    }  </script>  <!-- 1: script 加载回来的东西 被当作 js 执行 -->  <!-- getBook() -->  <script src="http://localhost:3000/api/getBook"></script>

2.后端实例代码:

const http = require('http')http.createServer((req, res) => {  console.log(req.url, req.method)  // 'Access-Control-Allow-Credentials': true 是否允许 cookie 传输  res.writeHead(200, {    'content-type': 'application/json',    'Access-Control-Allow-Origin': '*',    'Access-Control-Allow-Headers': 'x-auth, content-type',    'Access-Control-Allow-Methods': 'GET, PUT, POST, DELETE, OPTIONS',    'Access-Control-Allow-Credentials': true  })  // jsonP  res.end(`  getBook(${JSON.stringify({bookName: 'php'})})   `)}).listen(3000,() => {  console.log('启动成功: http://localhost:3000')})