前後端分離實踐 — 如何解決跨域問題

Justin_lu發表於2016-08-14

原文連結

隨著前端越來越火,越來越多的人推崇前後端分離,後端只提供API,前端只負責消費API。這樣我們就能更加專注自己的事情了,比如前端可以使用任何想要的工具(Webpack、Gulp等等),後端也不用因為整合前端的程式碼而苦逼加班了。這裡不討論前後端分離的必要性,更多可參考

這裡主要分享前後端分離後,如何解決跨域問題

服務端

Rails

作為一個Rails程式設計師,首先分享一下在Rails裡面的解決方案, 大家可以使用一個rack-cors 中介軟體,並作以下配置:

#config/application.rb
    config.middleware.insert_before 0, "Rack::Cors", :debug => true, :logger => (-> { Rails.logger }) do
      allow do
        origins [`http://localhost:3000`]
        resource `*`,
          :headers => :any,
          :methods => [:get, :post, :delete, :put, :options, :head],
          :max_age => 0
      end
    end

更多配置請參考 rack-cors

Node

當然,如果後端是NodeJs,我們也可以找到同樣的中介軟體 cors 請看以下配置

var express = require(`express`)
  , cors = require(`cors`)
  , app = express();

// 同樣的,只支援開發環境跨域
if(process.env.NODE_ENV == `development`){
    app.use(cors());
}

Nginx

這時候,後端程式設計師可能會說,為了保持跟生產環境配置一直,請直接用 Nginx 來配置吧,這樣能減少差異。啪啦啪啦…
直接看配置吧

server {
    listen       80;
    # 配置可訪問域名,注意需要新增相應host配置
    server_name xxx.dev;
    #charset koi8-r;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

    location /api/v1 {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Real-IP $remote_addr;
        # API Server
        proxy_pass http://localhost:4000;
        proxy_next_upstream error;
    }
    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Real-IP $remote_addr;
        # Frontend Server
        proxy_pass http://localhost:3000;
        proxy_next_upstream error;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

http-proxy-middleware

這時候前端也不服了,說,我們自己能搞定
PS: 其實這裡用了Nginx配置之後,webpack的hot reload會存在比較大的延遲,具體原因還沒研究

# 安裝外掛
cnpm install --save-dev http-proxy-middleware

# 新增配置
import proxy from `http-proxy-middleware`;

const apiProxy = proxy(`/api/v1`, {
    target: `http://localhost:4000`,
    changeOrigin: true,
    ws: true
});
browserSync({
  server: {
    baseDir: `src`,

    middleware: [
      apiProxy,
      ...
    ]
  }
})

更多參考

Chrome

你也可以通過新增chrome外掛來支援跨域
CORS Toggle

相關文章