【问题标题】:JqueryAjax Webservice and Crossdomain problemJquery Ajax Web Service 和跨域问题
【发布时间】:2011-01-29 03:20:23
【问题描述】:

我的 Jqueryajax 调用有问题,它将通过跨域使用我的一种 Web 服务方法。我一直在尝试所有可能的方法来完成,但仍然没有成功。请帮我解决我做错的事情。我可能需要为某些安全设置配置 Web 服务器吗?下面是我的代码。如果您对我的代码有任何疑问,请告诉我。

//Using Ajax Post
//Webservice will return JSON Format
//Doesn't work in both FF and IE when host to live server , work in local
//Error : Access is denined in xxxx.js in IE
//Http 403 Forbidden in FF , FF request header is OPTION
//this approach is the simplest and best way for me to use


    var myID = $("myID").val();
   $.ajax({
    type: "POST",        
    url: "http://www.mywebsite.com/webservice/Webservice.asmx/getInfo",
    data: "{myID:'"+ myID + "'}",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function(data) {

           Dostuff(data);
        },

    error: FailureCallBack

});

我的网络服务将如下所示

using System.Web.Script.Services;
[WebService(Namespace = "http://www.mywebsite.com/webservice/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class Webservice : System.Web.Services.WebService
{
    [WebMethod]
    [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
    public object getInfo(string myID)
    {       
            //Do stuff here
            return getJSONDataFromDataSet(_DS); 
    } 


}

 

//second Approch <br/>
//Using Ajax GET , webservice will return XML Format <br/>
//Doesn't work in both FF and IE when host to live <br/>
//Error : Access is denined in xxxx.js in IE <br/>
//returning XML data in FF but showing nothing in page <br/>

var myID = $("myID").val();
     $.ajax({

        type: "GET",

        url: "http://www.mywebsite.com/webservice/Webservice.asmx/getInfo?myID="myID"&callback=?",    

        success: function(data) {

                Dostuff(data);
            },

        error: FailureCallBack

    });

网络服务

public SerializableDictionary<string, object> getInfo(string myID)
    {         
     //Do stuff here
            SerializableDictionary<string, object> obj = getJSONFromDataTable(_DS);            
            return obj;            
    }

 

//third Approch
//Using normal GET , webservice will return XML Format
//same problem with second approch



var myID = $("myID").val();
    var xmlhttprequest = createRequestObject();
    var url = 'http://www.mywebsite.com/webservice/Webservice.asmx/getInfo?myID='myID'';
    xmlhttprequest.open("GET", url, true);
    xmlhttprequest.onreadystatechange = getData;
    xmlhttprequest.send(null);
function getData() 
{
  if ((xmlhttprequest.readyState == 4) &&( xmlhttprequest.status == 200))
  {    
    var myXml = xmlhttprequest.responseXML;
    Dostuff(myXml);
  } 
}
function createRequestObject() 
{
      if (window.XMLHttpRequest) 
      {
                return xmlhttprequest = new XMLHttpRequest(); 
      } 
      else if (window.ActiveXObject) 
      {  
            return xmlhttprequest = new ActiveXObject("Microsoft.XMLHTTP"); 
      } 
}

Webservice 与第二种方法相同

编辑: 现在我得到访问被拒绝,IE 中 POST 和 GET 请求的 javascript 错误。 在提琴手中,我可以看到 Firefox 返回 Xml 数据,但页面中没有显示任何内容,因此我在 getData 中放置了一个警告框 函数,myXml 变量值始终为空,奇怪的是我只放了 1 个警报框,它显示警报 3 次。 下面是我的代码

  var myID = $("myID").val();
    var xmlhttprequest = createRequestObject();
    var encodeUrl = escape(_utf8_encode("http://www.mywebsite.com/webservice/Webservice.asmx/getInfo?myID="myID)); 
    var url = 'http://www.mywebsite.com/webservice/proxy.aspx?url='+encodeUrl;
    xmlhttprequest.open("GET", url, true); //**ACCESS IS DENIED HERE in this line!!!!**
    xmlhttprequest.onreadystatechange = getData;
    xmlhttprequest.send(null);


function getData() 
{
    var myXml = xmlhttprequest.responseXML;
    alert(myXml); //ALWAYS NULL and show alert 3 times????
    DoStuff(myXml);
}

请帮忙。 最好的问候

【问题讨论】:

    标签: asp.net jquery ajax web-services crossdomain.xml


    【解决方案1】:

    出于安全原因,ajax 请求将无法跨域工作。有两种解决方案。

    1. 向同一个服务器发出请求,然后使用基于服务器的代理机制向另一个域发出请求。

    2. 使用“JSONP”,这是另一种生成类似 ajax 请求的交叉方式。 jQuery 通过 dataType: jsonp 而不是 json 支持这一点,并且通过他们的 api 文档有进一步的解释。此博客条目可能有用 - http://bloggingabout.net/blogs/adelkhalil/archive/2009/08/14/cross-domain-jsonp-with-jquery-call-step-by-step-guide.aspx

    【讨论】:

    • 感谢您的快速响应,将尝试更新状态
    • 为了让 jsonp 工作,“其他”服务器必须接受跨域请求并做出相应的响应。但 jsonp 不是 SOAP,因此除非 OP 能够/愿意从 SOAP 更改为 JSON/JSONP,否则该选项不可用。正如您所说,使用服务器端代理是解决此问题的方法/
    • 嗨,leeeb,问题是我想从网络服务传递我的字典之一,而不仅仅是一个简单的字符串。如果我使用 ajax post ,非常容易,但是如果我使用 get ,我会在提琴手中收到错误消息“生成 xml 错误”。所以我在发送之前尝试对我的字典进行序列化,现在可以,但它只能在本地工作。
    【解决方案2】:

    您需要在您的域上创建代理并传递请求,请在此处解释:http://www.johnchapman.name/aspnet-proxy-page-cross-domain-requests-from-ajax-and-javascript/

    【讨论】:

    • 嗨 KIvanov,刚才我使用您的链接进行了测试。 Proxy.aspx 但没有运气。错误完全相同。我可以得到 xml 结果和 Http 响应状态是 200 OK。但 FF 中没有显示任何内容,并且在 IE 中访问被定义错误。
    • 我已经成功地使用了它,我不知道是否有任何其他简单的方法来做到这一点
    【解决方案3】:

    非常感谢大家的回复和帮助。 我已经解决了这个问题:D 解决方案是使用 JSONP 和 Javascript 动态注入到 html 页面。 下面是代码

    HTML

    <body>
    <script type="text/javascript">
    var url = "http://www.mywebsite.com/Javascript/MYJS.js";
    
    var script = document.createElement("script");       
    script.setAttribute("src",url);
    script.setAttribute("type","text/javascript");                
    document.body.appendChild(script);
    </body>
    </script>
    

    MYJS.js

    var myID = $("#myID").val();
    var url = "http://www.mywebsite.com/Webservice.aspx/getInfo?myID="+myID+"";
    
       if (url.indexOf("?") > -1)
                url += "&jsonp=" ;
            else
                url += "?jsonp=" ;
            url += "ShowInfoCallback" + "&" ; //Important put ur callback function to capture the JSONP data
    
           url += new Date().getTime().toString(); // prevent caching        
    
    
    
    
    var script = document.createElement("script");        
        script.setAttribute("src",url);
    
        script.setAttribute("type","text/javascript");                
        document.body.appendChild(script);
    
    
    function ShowInfoCallback(data)
    {
     DoWhateverYouWant(data);    
    }
    

    Webservice.aspx.cs

    using System.Web.Script.Serialization;
    public partial class Webservice : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(Request.QueryString["myID"]))
                this.getInfo();
            else
                this.getInfoDetails();
    
        }
        public void getInfo()
        {
            string Callback = Request.QueryString["jsonp"];
            string encryptedID = Request.QueryString["myID"];
    
            //Dowhateveryouwanthere
    
            object obj = getJSONFromDataTable(myDataSet.Tables[1]);
            JavaScriptSerializer oSerializer = new JavaScriptSerializer();
            string sJSON = oSerializer.Serialize(obj);
            Response.Write(Callback + "( " + sJSON + " );");
            Response.End();
        }
        public void getInfoDetails()
        {
            //Same as above
     //returning 2 tables , Info and InfoDetails
            Response.Write(Callback + "( { 'Info' : " + sJSONDetails +",'InfoDetails' : "+ sJSONService + " } );");
            Response.End();
        }
    }
    

    再次感谢

    【讨论】: