访问.asmx webservice跨域并将结果加载到级联下拉列表中



我有两个站点

我也有一个webservice.

当我在:http://www.mydomain.com/trouwlocaties/zoeken-uitgebreid

上通过级联下拉菜单加载国家名称时,就可以看到这个效果了

然而,同样的web服务在:http://otherdomain.com/weddingvenues/search-advanced上抛出错误正如你所看到的下拉菜单显示'方法错误-1',在我的Chrome控制台中我看到:500(内部服务器错误),其中客户端试图获取.asmx服务,在toptrowen上它使用POST(这是我相信应该发生的事情,也更安全)。

这是getnations webservice:

<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<ToolboxItem(False)> _
Public Class geolocation
'<System.Web.Script.Services.ScriptService()> _
'<WebService(Namespace:="http://tempuri.org/")> _
'<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
'<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _

Inherits System.Web.Services.WebService
<WebMethod()> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue()
    Dim values As New List(Of CascadingDropDownNameValue)
    Dim myConnection As SqlConnection = GetConnection()
    Dim cmd As New SqlCommand(String.Format("SELECT id,name as title FROM country order by title asc", Threading.Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName), myConnection)
    Try
        myConnection.Open()
        Dim reader As SqlDataReader = cmd.ExecuteReader
        Dim CountryName As String
        Dim CountryID As Integer
        While reader.Read
            CountryName = reader("title").ToString
            Int32.TryParse(reader("id"), CountryID)
            values.Add(New CascadingDropDownNameValue(CountryName, CountryID.ToString))
        End While
    Catch ex As Exception
    Finally
        myConnection.Close()
    End Try
    Return values.ToArray
End Function
End Class   

首先我试着把这个添加到我的web.config:

<system.web>
<webServices>
  <protocols>
    <remove name="Documentation"/>
    <add name="HttpGet"/>
    <add name="HttpPost"/>
  </protocols>
</webServices>
</system.web>

这样做之后,我在我的Chrome控制台收到这个:

Uncaught SyntaxError: Unexpected token < 

显然结果没有被解释为XML,但我猜是JSON。经过一些Google搜索,我认为这与MIME类型有关,但我从来没有发现如何将此服务更改为XML。

所以我继续搜索,发现了一些别的东西,我正在阅读这些帖子:http://social.msdn.microsoft.com/forums/en-us/asmxandxml/thread/F80BDA62-C87A-4BDA-8CB1-F2CFAD1C8891未捕获的SyntaxError: Unexpected token <——jQuery中ajax

显然这可能是一个"跨域问题"。

所以我最终创建了这些文件:

clientaccesspolicy.xml

<?xml version="1.0" encoding="utf-8"?>
<access-policy>
  <cross-domain-access>
<policy>
  <allow-from http-request-headers="*">
    <domain uri="*"/>
  </allow-from>
  <grant-to>
    <resource path="/" include-subpaths="true"/>
  </grant-to>
</policy>
  </cross-domain-access>
</access-policy>

crossdomain.xml

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<?xml version="1.0" ?> 
<cross-domain-policy>
    <allow-access-from domain="*" /> 
    <allow-access-from domain="*.otherdomain.com" secure="false" /> 
</cross-domain-policy>
<configuration>
    <system.serviceModel>
        <bindings>
            <basicHttpBinding>
            <binding name="GetCountries" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647"> 
                <security mode="None" />
            </binding>
            </basicHttpBinding>
        </bindings>
        <client>
            <endpoint address="http://www.mydomain.com/geolocation.asmx"
            binding="basicHttpBinding" name="GeoLocation" />
        </client>
    </system.serviceModel>
</configuration> 

在第一个示例链接中,用户还添加了属性bindingConfiguration="DashboardServiceSoap"和contract="DashboardService. "DashboardServiceSoap",但我不知道我应该在那里为我的情况填写什么。

我仍然卡住了,我不知道什么是正确的轨道,也不知道如何配置我的设置。

更新21-06-2013

更新了我的网页。配置:

<system.webServer>
    <httpProtocol>
        <customHeaders>
            <add name="Access-Control-Allow-Origin" value="*" />
            <add name="Access-Control-Allow-Headers" value="Content-Type" />
      </customHeaders>
    </httpProtocol>

我还尝试了以下4种配置:

<System.Web.Script.Services.ScriptService()> _
<System.Web.Services.WebService(Namespace:="http://tempuri.org/")> _
<System.Web.Services.WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)> _
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
<ToolboxItem(False)> _
Public Class geolocation
    Inherits System.Web.Services.WebService

场景1和2使用这个方法定义:

<WebMethod()> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue() 

场景1:web中的WITH协议部分。配置

<webServices>
  <protocols>
    <remove name="Documentation"/>
    <add name="HttpGet"/>
    <add name="HttpPost"/>
  </protocols>
</webServices>  

在。nl域名上正确工作在。com域上抛出方法错误-1。Chrome控制台显示:Uncaught SyntaxError: Unexpected token

场景2:web中没有协议部分。配置

在。nl域名上正确工作在。com域上抛出方法错误-1。Chrome控制台显示:GET http://www.otherdomain.com/geolocation.asmx/GetCountries?knownCategoryValues=%22%22&category=%22Country%22&callback=Sys._jsonp0 500 (Internal Server Error) ScriptResource.axd:7773

使用此方法定义的场景3和4:

<WebMethod()> _
<ScriptMethod(UseHttpGet:=True, ResponseFormat:=System.ServiceModel.Web.WebMessageFormat.Json)> _
Public Function GetCountries(ByVal knownCategoryValues As String, ByVal category As String) As CascadingDropDownNameValue() 

场景3:web.config

WITH protocols部分
<webServices>
  <protocols>
    <remove name="Documentation"/>
    <add name="HttpGet"/>
    <add name="HttpPost"/>
  </protocols>
</webServices>  

在。nl域上抛出方法错误500。Chrome控制台显示:POST http://www.mydomain.com/geolocation.asmx/GetCountries 500(内部服务器错误)catch .js:197在。com域名下拉列表中抛出方法错误-1。Chrome控制台显示:Uncaught SyntaxError: Unexpected token

场景4:web.config

在。nl域上抛出方法错误500。Chrome控制台显示:加载资源失败:服务器响应状态为500(内部服务器错误)在。com域名下拉列表中抛出方法错误-1。Chrome控制台显示:GET http://www.otherdomain.com/geolocation.asmx/GetCountries?knownCategoryValues=%22%22&category=%22Country%22&callback=Sys._jsonp0 500 (Internal Server Error)

我也没有显式地从脚本中调用.asmx,我让级联下拉为我做这项工作。像这样:

<asp:DropDownList ID="ddlCountries" CssClass="textbox" AutoPostBack="true" runat="server"></asp:DropDownList>
<cc1:cascadingdropdown ID="cddCountries" runat="server" Category="Country" Enabled="True" LoadingText="<%$Resources:Glossary,loading %>" PromptText="<%$Resources:Glossary,country_choose %>" 
ServiceMethod="GetCountries" TargetControlID="ddlCountries">
</cc1:cascadingdropdown>

后台代码

cddCountries.ServicePath = "http://www.mydomain.com/geolocation.asmx"

我不知道我使用这些预定义元素的事实是否与我的问题有关,我可以更好地通过脚本自己调用.asmx服务并填充下拉列表。如果是,我不知道怎么做。

你是正确的,这是一个跨原产地的问题。有几种方法可以处理这个问题:

  1. 您可以将web服务转换为JSONP,只要需要转到web服务的数据不是非常大。来自服务的数据可以像你喜欢的那样大。不要太大,它必须是大约2k个字符或更少-您可以通过知道它是作为从脚本标记的src属性的get请求的一部分发送的,来计算一个JSONP请求中可以发送的数据量。

    这里有一个很好的关于JSONP的答案,你可能已经很熟悉了:

    JSONP是关于什么的?

    下面是一个在VB中做JSONP的例子。净:

    http://www.sattsoft.com/tutorials/contents/1/14/cross-domain-call-using-ajax-jquery-jsonp-and-vb-net-web-service.html

  2. 您可以创建www.wunderweddings.com的子域,也许称之为"api.www.wunderweddings.com",并使用DNS使用a或CNAME记录将该子域指向正确的位置。然后,您将嵌入一个微小的(不可见的)iframe到您的客户端页面,它将指向这个新的api主机(一定要指定src为"//api.www.underweddings.com",以便匹配包含页面的http/s),并在iframe中使用javascript来推广其文档。域到www.wunderweddings.com,你可以通过脚本注入,但它更容易只是有该页面在服务器上提供的脚本来做,然后你可以自由地通信之间的iframe指向你的API和包含iframe的页面是www.wunderweddings.com。iframe中的代码会为你访问web服务,获取数据,推广文档。域,并通知包含该页。

  3. 如果你知道postMessage在你的客户端总是可用的(可能不是虽然),你可以做上面没有改变document.domain

  4. 上面的第2点和第3点可能听起来很麻烦!特别是如果你打算扩展你提供的web服务和/或访问该服务的域的数量。如果是这样,我强烈推荐使用EasyXDM,它是一个非常棒的、非常强大的库,用于执行客户端跨域RPC:

    http://easyxdm.net/wp/

    EasyXDM在postMessage不可用的情况下提供了回退,例如通过散列或name属性进行通信,以及其他一些事情。

  5. 你可以修复crossdomain.xml。这是我有点生疏的地方,但我会给你我最好的猜测:

你希望你的crossdomain.xml像这样:

<?xml version="1.0" ?> 
<cross-domain-policy>
    <allow-access-from domain="*" /> 
    <allow-access-from domain="*.wunderweddings.com" /> 
</cross-domain-policy>

""的第一个子域,即""将使其完全不受限制,而""将使浏览器只允许wunderweddings.com和子域进行跨域调用。您不需要两个"allow-access-from"标签,但至少需要其中一个。

我不知道为什么配置的东西在那里,它不应该在那里。我第一次完全没有注意到,这几乎肯定是你的问题。还要确保crossdomain.xml是从另一个服务器(具有web服务的服务器)提供的。

澄清一下,crossdomain。XML底部不应该有额外的XML 标签和它里面的所有东西都是从某处漏进来的不应该在crossdomain。xml


最终更新

对于那些有类似问题的人来说,Floran发现了无效字符的问题:

这个必须被添加到页面的顶部:

<asp:ScriptManagerProxy ID="ScriptManagerProxy1" runat="server"> 
<Services> 
<asp:ServiceReference Path="geolocation.asmx" /> 
</Services> 
</asp:ScriptManagerProxy>

相关内容

  • 没有找到相关文章

最新更新