跨域問題的解決方案

什麼是跨域?

跨域問題是由於瀏覽器的同源策略形成的,是瀏覽器對javascript 實施的安全策略。使得瀏覽器不能執行網站請求。
當咱們訪問api接口的時候,在瀏覽器上會出現javascript

Access to XMLHttpRequest at ' http://localhost:7002/test' from origin ' http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

同源策略:前端

URL 是否容許通訊
同一域名 容許
同一域名,不一樣端口 不容許
同一域名,不一樣協議 不容許
域名和域名對應的IP 不容許
主域名和子域名 不容許
不一樣域名 不容許
怎樣解決跨域問題
1.JSONP

script 標籤的src 屬性在同源策略問題上就不會遇到跨域的問題,所以能夠使用這種請求方式來實現http請求.
前端代碼:java

function createJsonp(url,callback) {
        let jsonp = document.createElement('script');
        let data;
        jsonp.type = "text/javascript";
        jsonp.src = `${url}?callback=jsonCallback`;
        document.getElementsByTagName('head')[0].appendChild(jsonp);
        setTimeout(() => {
            document.getElementsByTagName('head')[0].removeChild(jsonp)
        }, 500);

        window.jsonCallback = (result) => {
            callback(result)
        }
    }
    createJsonp('http://localhost:7002/test',function(data){
        console.log(data)
    }) ;

前端能夠經過回調函數獲取須要的數據
後端代碼:json

async test(){
    const {ctx} =this;
    const cb = ctx.queries.callback;
    ctx.set('Content-Type','application/javascript;charset=utf-8')
    let data = {
      name:'name1',
      age:20
    }
    ctx.body = cb+`(${JSON.stringify(data)})`
  }
2.使用Nginx 反向代理
# 第一種
server {
    listen      8080;
    server_name 須要代理的服務地址(localhost)
    location / {
        proxy_pass   轉發到服務地址(http://localhost:7002);
    }
}
#第二種
server
{
    listen 80;
    server_name 須要代理的服務地址(localhost);
    location /ok {
        proxy_pass http://localhost:7002;
        #   容許跨域的方法,*表明全部(GET,POST,DELETE,PUT...)
        add_header Access-Control-Allow-Methods *;
        #   指定本次預檢請求的有效期,單位爲秒,,在此期間不用發出另外一條預檢請求。
        add_header Access-Control-Max-Age 3600;
        #   帶cookie請求須要加上這個字段,並設置爲true
        add_header Access-Control-Allow-Credentials true;
        #   表示容許這個域跨域調用(客戶端發送請求的域名和端口) 
        #   $http_origin動態獲取請求客戶端請求的域   不用*的緣由是帶cookie的請求不支持*號
        add_header Access-Control-Allow-Origin $http_origin;

        #   表示請求頭的字段 動態獲取
        add_header Access-Control-Allow-Headers 
        $http_access_control_request_headers;

        #   OPTIONS預檢命令,預檢命令經過時才發送請求
        #   檢查請求的類型是否是預檢命令
        if ($request_method = OPTIONS){
            return 200;
        }
    }
}
3.CORS

Cors 是使用自定義的HTTP頭部讓瀏覽器與服務器進行數據交換,從而決定請求響應是否應該成功。
須要在後臺服務上進行配置
例如在egg.js中使用:
須要下載安裝egg-cors 插件(略過)後端

// 配置的參數
{String|Function(ctx)} origin `Access-Control-Allow-Origin`, default is request Origin header
{String|Array} allowMethods `Access-Control-Allow-Methods`, default is 'GET,HEAD,PUT,POST,DELETE,PATCH'
{String|Array} exposeHeaders `Access-Control-Expose-Headers`
{String|Array} allowHeaders `Access-Control-Allow-Headers`
{String|Number} maxAge `Access-Control-Max-Age` in seconds
{Boolean} credentials `Access-Control-Allow-Credentials`
{Boolean} keepHeadersOnError Add set headers to `err.header` if an error is thrown
相關文章
相關標籤/搜索