也许你们中的一些人可以帮助我更好地理解javascript同源策略。
相同的原始政策定义如下(http://en.wikipedia.org/wiki/Same_origin_policy):
在计算中,相同的源策略是许多浏览器端编程语言(如JavaScript)的重要安全概念。该策略允许在源自同一站点的页面上运行的脚本在没有特定限制的情况下访问彼此的方法和属性,但阻止访问不同站点上的页面中的大多数方法和属性。
我已使用网址
向Google App Engine部署了一个GWT应用程序http://metalsandstocks.appspot.com
由于GWT将所有java编译成javascript,这意味着我的应用程序部署为javascript。由于这是一个ajax应用程序,我认为它需要遵守相同的原始策略。该应用程序使用ajax来调用不同的域(http://finance.yahoo.com),以便获得显示给用户的实时股票报价。该应用程序按照描述的方式工作,但它具有与它所要求的更新不同的域。此应用是否违反了相同的原始政策?为什么或为什么不呢?
答案 0 :(得分:5)
您可以使用JSONP获取Yahoo Finance,因此这绝对是您正在使用的内容。
示例网址是......
http://d.yimg.com/autoc.finance.yahoo.com/autoc?query=Apple&callback=YAHOO.Finance.SymbolSuggest.ssCallback
当请求加载后,它将调用您在GET参数中定义的回调。这允许您解决相同的源策略,前提是该服务支持JSONP。
或者,有些人将他们的服务器用作代理。
答案 1 :(得分:4)
CORS(跨域资源共享)是允许跨域AJAX调用的标准方法。
这很简单。例如,如果将HTTP标头Access-Control-Allow-Origin: *
添加到页面(例如使用PHP),那么来自任何域的JavaScript将能够使用AJAX读取页面。如果此类标头不存在,则同源策略将阻止来自其他域的AJAX调用读取该页面。
使用CORS,页面的所有者(例如,公开特定数据或API的页面)可以公开该页面(仅限该页面)以供其他人从他们自己的域中调用。原则是,如果页面的所有者明确说“其他人可以访问我的东西”,那么CORS将允许它。否则,假定采用相同的站点策略。
答案 2 :(得分:4)
在服务之间访问数据与从另一个域调用在一个域上定义的JavaScript函数不同。
换句话说,我认为你混淆了“同源策略”(例如,我的浏览器中的一个选项卡在浏览器的另一个选项卡中调用了在一个站点上定义的JS函数),JS获取数据来自URL(例如来自雅虎的股票价格)。
答案 3 :(得分:0)
以下是您需要做的事:JSONP。
由于上述政策,您无法向雅虎提出AJAX请求,但有一些解决方法。即脚本标记,它可以向任何地方发出请求。
例如,假设您想在用户点击“开始”按钮时向雅虎发出请求。您需要添加一个事件处理程序来捕获用户的click事件,然后将新脚本标记添加到DOM的head部分。脚本标记的URL很重要,它必须有一个回调参数,例如:
http://helloasdf.cloudfoundry.com/get.tokens?callback=xss
注意回调可以是任意函数名称。回复将是:
xss(["asdf"])
意味着代码中的xss函数将被传递[“asdf”]。
或w / yahoo的API;
注意回调= YAHOO.Finance.SymbolSuggest.ssCallback它将在请求返回时调用该函数:
YAHOO.Finance.SymbolSuggest.ssCallback({"ResultSet":{"Query":"gs","Result":[{"symbol":"GS","name": "The Goldman Sachs Group, Inc.","exch": "NYQ","type": "S","exchDisp":"NYSE","typeDisp":"Equity"},{"symbol":"^GSPC","name": "S&P 500 INDEX,RTH","exch": "SNP","type": "I","typeDisp":"Index"},{"symbol":"GSS","name": "Golden Star Resources, Ltd.","exch": "ASE","type": "S","exchDisp":"AMEX","typeDisp":"Equity"},{"symbol":"^GSPTSE","name": "S&P/TSX Composite index (Interi","exch": "TOR","type": "I","exchDisp":"Toronto","typeDisp":"Index"},{"symbol":"GSK","name": "GlaxoSmithKline plc","exch": "NYQ","type": "S","exchDisp":"NYSE","typeDisp":"Equity"},{"symbol":"GSX","name": "Gasco Energy Inc.","exch": "ASE","type": "S","exchDisp":"AMEX","typeDisp":"Equity"},{"symbol":"OIL","name": "iPath S&P GSCI Crude Oil TR Index ETN","exch": "PCX","type": "E","typeDisp":"ETF"},{"symbol":"GSIC","name": "GSI Commerce Inc.","exch": "NMS","type": "S","exchDisp":"NASDAQ","typeDisp":"Equity"},{"symbol":"GST","name": "Gastar Exploration, Ltd.","exch": "ASE","type": "S","exchDisp":"AMEX","typeDisp":"Equity"},{"symbol":"GSI","name": "General Steel Holdings, Inc.","exch": "NYQ","type": "S","exchDisp":"NYSE","typeDisp":"Equity"}]}})
以下是动态添加脚本标记所需的js示例:
var headLoc = document.getElementsByTagName("head").item(0);
var scriptObj = document.createElement("script");
var token="localstring"
var url="http://helloasdf.cloudfoundry.com/get.tokens?callback=xssCallback";
// Add script object attributes
scriptObj.setAttribute("type", "text/javascript");
scriptObj.setAttribute("charset", "utf-8");
scriptObj.setAttribute("src", url);
scriptObj.setAttribute("id", 'asf12');
headLoc.appendChild(scriptObj);
我在这里更详细地记录了这个过程:http://eggie5.com/22-circumvent-same-origin-policy