成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

用 nginx 代理 MailChimp API 并支持跨域

djfml / 1392人閱讀

摘要:接下來(lái)我們開(kāi)始編寫(xiě)自己的配置文件,實(shí)現(xiàn)指向的代理,并在請(qǐng)求中添加進(jìn)行鑒權(quán),同時(shí)在響應(yīng)中添加跨域頭,以滿足跨域需求。在上面的配置文件中,用我們從創(chuàng)建的代替,用需要實(shí)現(xiàn)訂閱的郵件列表的代替,而則是的后綴數(shù)字。

tl;dr

nginx 既靈活方便,又功能豐富,可以幫助我們實(shí)現(xiàn)添加跨域頭、URL 重寫(xiě)以及隱藏敏感信息等功能。本文介紹在使用 MailChimp
進(jìn)行郵件營(yíng)銷中遇到的一個(gè)普遍問(wèn)題,分析了瀏覽器發(fā)起跨域請(qǐng)求時(shí),在瀏覽器和服務(wù)器之間的交互過(guò)程,在此基礎(chǔ)上提供了一個(gè)使用 nginx
反向代理實(shí)現(xiàn)的、靈活經(jīng)濟(jì)的解決方案。


MailChimp是最大的郵件營(yíng)銷解決方案提供商,官方網(wǎng)站 https://mailchimp.com。

通過(guò) MailChimp 可以定制郵件模板、創(chuàng)建自己的郵件列表、發(fā)起各種營(yíng)銷活動(dòng),并支持統(tǒng)計(jì)有多少人打開(kāi)了郵件以及其他一些 SNS 功能,客戶可以隨時(shí)訂閱或取消訂閱郵件。

MailChimp 提供了多種訂閱表單,如普通表單、嵌入表單、彈窗表單以及由第三方集成的表單……用于收集用戶郵箱及其他一些個(gè)人信息,然而這些表單都存在一些問(wèn)題,如普通表單必須進(jìn)行 captcha 校驗(yàn),嵌入表單及彈窗表單不支持注冊(cè)后自動(dòng)跳轉(zhuǎn)到自己的頁(yè)面,并且所有這些表單還需要用戶在收件箱里收取確認(rèn)郵件并確認(rèn)訂閱,對(duì)于一家迫切需要更多訂閱用戶實(shí)現(xiàn)郵件營(yíng)銷的公司來(lái)說(shuō),為了盡可能多地獲取訂閱用戶,這些校驗(yàn)和確認(rèn)能省則省。而第三方集成的表單則需要按月收費(fèi),每月十幾到上百美元不等,好鋼要用在刀刃上,這也是一筆能省則省的開(kāi)支。


MailChimp 還提供了 API 接口,其中 與列表成員相關(guān)的 API 接口 包含列表成員的創(chuàng)建、讀取、編輯以及刪除功能,因此,可以通過(guò) AJAX 方式進(jìn)行郵件訂閱,訂閱流程中是否加入 captcha 校驗(yàn)完全自主,用戶訂閱之后也不需要進(jìn)行郵箱確認(rèn),并且完全免費(fèi)。

但這些 API 也存在兩個(gè)問(wèn)題,一是不支持跨域,二是 MailChimp 提供的 API key 是全權(quán)限的,意味著一旦泄露,搗蛋分子就可以利用 MailChimp 的 API 接口對(duì)你的 MailChimp 賬號(hào)為所欲為。

因此,我們?nèi)绻M褂?MailChimp 的 API 實(shí)現(xiàn)用戶訂閱,就需要解決上述兩個(gè)問(wèn)題,兼具靈活性和功能性的 nginx 是個(gè)不錯(cuò)的選擇。


首先我們需要一個(gè) nginx,在本地試驗(yàn)的話用 docker 就可以了,在命令行終端執(zhí)行 docker pull nginx,稍等片刻就可把 nginx 最新版的 docker 鏡像拉取下來(lái)了。如果網(wǎng)絡(luò)狀況不佳,還可以配置 daocloud 的 Docker 加速器。

打開(kāi)終端窗口運(yùn)行 docker run --name temp-nginx nginx,再打開(kāi)一個(gè)終端窗口,然后使用 docker cp temp-nginx:/etc/nginx/nginx.conf. 和 docker cp temp-nginx:/etc/nginx/conf.d/default.conf. 這兩個(gè)命令從容器中將 nginx 相關(guān)的配置拷貝出來(lái),拷貝出來(lái)的配置文件主要作為我們自己編寫(xiě)配置文件的參考,即使之前沒(méi)有配置過(guò) nginx,也可以依葫蘆畫(huà)瓢完成基本的配置。

nginx.conf 文件中通過(guò) include 指令包含了 default.conf 文件的內(nèi)容,我們首先把兩個(gè)文件簡(jiǎn)化合并成一個(gè)文件,并刪除不必要的注釋,命名為 mailChimp.conf。

user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
  }
}

目的達(dá)到,我們可以“卸磨殺驢”,隨后運(yùn)行 docker stop temp-nginx && docker rm temp-nginx 將前面創(chuàng)建的容器停止并刪除。


為了方便調(diào)試,我們同時(shí)編寫(xiě)一個(gè) shell 腳本,用于隨時(shí)使用創(chuàng)建的 mailChimp.conf 配置文件啟動(dòng) docker 容器,并將 localhost 的 8080 端口綁定到容器的 80 端口上,這樣我們就可以向 http://localhost:8080/ 發(fā)起請(qǐng)求,并在命令行終端查看日志,一旦配置出現(xiàn)問(wèn)題可以隨時(shí)使用 ctrl+c 停止 docker 容器,修改配置后重新運(yùn)行該腳本即可。

#!/usr/bin/env bash

docker rm mailChimp-nginx

docker run --name mailChimp-nginx -v /path/to/mailChimp.conf:/etc/nginx/nginx.conf:ro -it -p 8080:80 nginx

接下來(lái)我們開(kāi)始編寫(xiě)自己的配置文件,實(shí)現(xiàn)指向 MailChimp 的代理,并在請(qǐng)求中添加 API key 進(jìn)行鑒權(quán),同時(shí)在響應(yīng)中添加跨域頭,以滿足跨域需求。

user nginx;
worker_processes 1;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
  worker_connections 1024;
}

http {
  server {
    listen 80;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /maillist/subscribe {
      if ($request_method = GET) {
        return 403;
      }

      add_header Access-Control-Allow-Origin * always;
      add_header Access-Control-Allow-Methods PUT,OPTIONS;
      add_header Access-Control-Allow-Headers Content-Type;

      if ($request_method = OPTIONS) {
        return 204;
      }

      proxy_set_header Authorization "apikey {apiKey}";
      rewrite /maillist/subscribe/(.*)$ /3.0/lists/{listId}/members/$1 break;
      proxy_pass https://us{siteNumber}.api.mailchimp.com;
    }
  }
}

在上面的配置文件中,{apiKey} 用我們從 MailChimp 創(chuàng)建的 API key 代替,{listId} 用需要實(shí)現(xiàn)訂閱的郵件列表的 ID 代替,而 {siteNumber} 則是 API key 的后綴數(shù)字。


我們?nèi)匀皇褂?docker 鏡像中 /usr/share/nginx/html 目錄的內(nèi)容作為網(wǎng)站首頁(yè),同時(shí)添加一個(gè) /maillist/subscribe 路徑。

由于 MailChimp 的 API key 是全權(quán)限的,為避免用戶直接通過(guò)瀏覽器訪問(wèn) /maillist/subscribe/ 獲取 MailChimp 的 /3.0/lists/{listId}/members/ 的內(nèi)容,首先需要對(duì) HTTP Method 為 GET 的請(qǐng)求返回 403 Forbidden,在配置文件中通過(guò) if 指令進(jìn)行 Method 判斷,并通過(guò) return 指令返回 403 代碼。

基于我們?yōu)g覽器進(jìn)行跨域請(qǐng)求的了解,瀏覽器在正式發(fā)起跨域請(qǐng)求之前,先要發(fā)起一個(gè) Method 為 OPTIONS 的請(qǐng)求(Preflighted Requests,預(yù)檢請(qǐng)求),通過(guò)該請(qǐng)求獲取服務(wù)端的響應(yīng)以了解服務(wù)端是否支持跨域、支持哪些 Method、以及支持哪些 Header 等信息,簡(jiǎn)言之,獲取服務(wù)器支持的 HTTP 請(qǐng)求特性,這些響應(yīng)頭在 OPTIONS 請(qǐng)求的響應(yīng)以及正式請(qǐng)求響應(yīng)中必須一致。

因此我們接著進(jìn)行 HTTP 響應(yīng)頭的設(shè)置,由于后面我們對(duì)請(qǐng)求及響應(yīng)進(jìn)行了代理轉(zhuǎn)發(fā),而轉(zhuǎn)發(fā)的 MailChimp 響應(yīng)中不包含 Access-Control-Allow-Origin 跨域響應(yīng)頭,因此這里使用 add_header 添加 Access-Control-Allow-Origin 時(shí),需要在后面加上 always,表示始終加上 Access-Control-Allow-Origin。

此外還需要添加 Access-Control-Allow-Methods 和 Access-Control-Allow-Headers 響應(yīng)頭。

經(jīng)試驗(yàn),如果采用 MailChimp 列表成員添加的 API,使用 POST Method,實(shí)現(xiàn)訂閱郵件的添加,則當(dāng)用戶通過(guò)其他途徑退訂了列表之后,無(wú)法重新訂閱,因此改為采用 MailChimp 列表成員編輯的 API,這是一個(gè) PUT Method,請(qǐng)求 URL 路徑中包含用戶郵箱地址的 MD5 值,當(dāng)請(qǐng)求的用戶在列表中不存在時(shí)為添加,當(dāng)用戶存在時(shí)則為修改。因此這里的 Access-Control-Allow-Methods 設(shè)置為 PUT,OPTIONS。

MailChimp API 僅支持 JSON 格式的數(shù)據(jù),這需要在請(qǐng)求中設(shè)置 Content-Type 為 application/json; charset=utf-8,同時(shí)還需要在 nginx 的響應(yīng)中設(shè)置 Access-Control-Allow-Headers 為 Content-Type。

設(shè)置完畢,對(duì)于 Method 為 OPTIONS 的請(qǐng)求,我們不需要返回 body,因此再次使用 if 指令進(jìn)行 Method 判斷,并返回 204 代碼表示無(wú)正文。

最后,就是代理轉(zhuǎn)發(fā)的設(shè)置了,首先使用 proxy_set_header 指令設(shè)置鑒權(quán)請(qǐng)求頭,然后使用 rewrite 指令進(jìn)行 URL 重寫(xiě),使用正則表達(dá)式獲取 /maillist/subscribe/ 之后的 E-Mail 的 MD5,拼接成 MailChimp API 請(qǐng)求的 URL,最后,通過(guò) proxy_pass 指令實(shí)現(xiàn)代理轉(zhuǎn)發(fā)。


使用 Fetch 從前端發(fā)起請(qǐng)求,相關(guān)代碼如下,API key、list ID 等敏感信息已被隱藏:

var headers = new Headers()
headers.append("Content-Type", "application/json; charset=utf-8")

var body = "{"email_address":"[email protected]","status":"subscribed"}"

fetch("http://localhost:8080/maillist/subscribe/f1c49ab3e7dd54b1daee1f4bdc0a1f78", {
  method: "PUT",
  headers,
  body
}).then(res => res.json()).then(json => {
  console.log(json)
}).catch(err => {
  console.log(err)
})

從控制臺(tái)上看到結(jié)果如下:


實(shí)際項(xiàng)目中,body 使用 JSON.stringify 進(jìn)行序列化,請(qǐng)求路徑中的參數(shù)還需要使用 MD5 庫(kù)進(jìn)行 MD5 值計(jì)算。

最終的配置可以在 nginx 的 docker 鏡像基礎(chǔ)上創(chuàng)建一個(gè)包含了上述配置的 docker 鏡像,然后部署到 DaoCloud 或其他提供 docker 容器服務(wù)的站點(diǎn)上去。下面是一個(gè)部署在 DaoCloud 的代理,http://mario-studio.daoapp.io/,使用 Vue 創(chuàng)建了一個(gè)超級(jí)簡(jiǎn)單的 訂閱表單,歡迎大家訂閱我的郵件列表,雖然還不知道我會(huì)發(fā)些什么(手動(dòng)比心

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26830.html

相關(guān)文章

  • nginx 代理 MailChimp API 支持跨域

    摘要:接下來(lái)我們開(kāi)始編寫(xiě)自己的配置文件,實(shí)現(xiàn)指向的代理,并在請(qǐng)求中添加進(jìn)行鑒權(quán),同時(shí)在響應(yīng)中添加跨域頭,以滿足跨域需求。在上面的配置文件中,用我們從創(chuàng)建的代替,用需要實(shí)現(xiàn)訂閱的郵件列表的代替,而則是的后綴數(shù)字。 tl;dr nginx 既靈活方便,又功能豐富,可以幫助我們實(shí)現(xiàn)添加跨域頭、URL 重寫(xiě)以及隱藏敏感信息等功能。本文介紹在使用 MailChimp進(jìn)行郵件營(yíng)銷中遇到的一個(gè)普遍問(wèn)題,分...

    _ipo 評(píng)論0 收藏0
  • Nginx

    摘要:此外,其也能夠提供強(qiáng)大的反向代理功能。是由為俄羅斯訪問(wèn)量第二的站點(diǎn)開(kāi)發(fā)的,第一個(gè)公開(kāi)版本發(fā)布于年月日。 keepalived+nginx 實(shí)現(xiàn)高可用雙機(jī)熱備 + 負(fù)載均衡架構(gòu) 1 準(zhǔn)備4個(gè)ubuntu16.04虛擬機(jī)(啟用網(wǎng)卡二并使用橋接模式):A服務(wù)器:192.168.0.103 主B服務(wù)器:192.168.0.104 主(備) 前端工程師學(xué)習(xí) Nginx ...

    syoya 評(píng)論0 收藏0
  • 跨域解決方案(史上最易懂)

    摘要:跨域總結(jié)跨域思路跨域解決方案一般分為兩種前端解決,后端解決前端解決方案通過(guò)前端解決的思想就是,通過(guò)設(shè)置中間件把跨域的請(qǐng)求轉(zhuǎn)發(fā)一下,其實(shí)就是反向代理,比如想要訪問(wèn)豆瓣的接口很會(huì)有跨域問(wèn)題,但是如果請(qǐng)求的是就不存在跨域反向代理就是截取之后的請(qǐng)求 跨域總結(jié) 1.跨域思路 跨域解決方案一般分為兩種:前端解決,后端解決 1.1 前端解決方案 通過(guò)前端解決的思想就是,通過(guò)設(shè)置中間件把跨域的請(qǐng)求轉(zhuǎn)發(fā)...

    wh469012917 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<