2017-05-30 92 views
0

我試圖使用帶有Express的NodeJS服務器實現this article - "Using a Web Proxy"中描述的結構。我需要訪問嵌入式iframe的html,由於同源政策,這當然是不可能的。作爲一種解決方法,我想我可以簡單地在我的服務器上請求iframe,然後將它傳遞給客戶端。超越服務器端請求的同源策略 - NodeJS/Express

我在我的服務器上輸入了一個名爲/getIframe的入口點。

當客戶端請求/getIframe時,我的服務器將request設置爲所需的位置,並將頁面保存爲html文檔(使用fs),然後將其發送回客戶端。這工作正常,但所有包含在html中的腳本/ css都沒有被傳遞,因爲request只能得到html。

因此,我手動下載了腳本/ css,並且工作正常。這是代碼。

app.get('/getIframe', function(req, res, next) { 
    request("http://www.iframeurl.com/something", function(error, response, body) { 
    fs.writeFileSync('iframe.html', body, 'utf8'); 
    var html = fs.readFileSync('iframe.html', 'utf8') 
    res.send(html); 
    }); 
}) 

調用這樣

<iframe src={"/getIframe"}></iframe> 

現在我的行​​爲我一直在尋找,但手動下載腳本的需求並不理想。

有沒有辦法在Node服務器上請求一個頁面,並將它傳遞給客戶端的所有內容(腳本,CSS等)?

我正在尋找的是類似

app.get('/getIframe', function(req, res, next) { 
    request("http://www.iframeurl.com/something", function(error, response, body) { 
    //pass on the requested page in a response with res.send(thePage) or render it with res.render(..) 
    }); 
}) 

UPDATE

我試着通過@Dafuck,雖然它是重定向到所需地址的更好的方式給出了答案,資源問題依然存在。

@Dafuck提出了下列溶液

app.use('/getIframe', function(req, res, next) { 
    request.get({ url: "http://www.iframeurl.com/something" }).pipe(res); 
}) 

其也可以與

app.use('/getIframe', function(req, res, next) { 
    req.pipe(request("http://www.iframeurl.com/something")).pipe(res); 
}) 

兩種溶液重定向到從該HTML被轉發所需的地址來實現。這很好。問題是檢索到的html的<head>中包含的所有腳本/鏈接都指向服務器地址,如http://localhost:3000,這些地址顯然不存在。

示例:http://www.example.com的HTML看起來像這樣

<!DOCTYPE html> 
<html> 

<head> 
    <meta http-equiv=content-type content="text/html; charset=utf-8" lang=en> 
    <meta name=viewport content="width=device-width" /> 
    <link href="somecss.css" rel="stylesheet"> 
    <script type="text/javascript" src="somejs.js"></script> 
</head> 

<body> 
    Example 
</body> 

</html> 

無論使用上述兩種方法,要求從我的服務器/getIframe將返回http://www.example.com瀏覽器將嘗試獲取正確的HTML somejs.jssomecss.csshttp://localhost:3000以及如前所述,失敗,因爲所有資源都在http://www.emample.com上找到。

我試過另一種方法,使用http-proxy

const httpProxy = require('http-proxy'); 
const apiProxy = httpProxy.createProxyServer(
    { 
    prependPath: false, 
    ignorePath: true, 
    changeOrigin: true, 
    xfwd: true, 
    } 
); 

app.all("/getIframe", function(req, res) { 
    apiProxy.web(req, res, {target: "http://www.example.com"}); 
}); 

不幸的是,似乎最後的解決方案是死路一條,因爲我從我想要獲取的源獲得奇怪的響應。我的猜測是源代碼阻止添加x-forward頭文件。

回答

0

只要管請求水庫,以在響應

request.post({ url: 'http://www.example.com', form: { foo: 'bar' }}).pipe(res); 

這主要是與此類似返回頁面結果:

request.get({url: "http://yolo"},function(err, response, body){ 
    if(err) return res.end(); 

    res.write(body); 
    res.setStatus(response.statusCode); 
    res.setHeader("Content-type", response.headers['content-type']); 
    return res.end(); 
}); 
+2

儘管此代碼可以回答這個問題,提供關於如何解決問題和/或爲何解決問題的附加背景可以提高答案的長期價值。 – Badacadabra

+0

看看更新的問題@Dafuck – Percolator