使用 javascript (JQuery Request) 向 wp8 推送通知

Posted

技术标签:

【中文标题】使用 javascript (JQuery Request) 向 wp8 推送通知【英文标题】:Push notification to wp8 using javascript (JQuery Request) 【发布时间】:2014-04-27 18:46:18 【问题描述】:

所以我要做的是使用 javascript 将通知推送到 Windows 8 应用程序。

所以在检查了这个网站后,这是我发现的唯一有用的网站。

http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202977(v=vs.105).aspx

我明白以下内容:

1- 您需要开发一个请求推送通知服务 URI 的应用程序,然后该 URI 将与推送客户端服务共享。

(此应用程序的代码不需要任何内容​​,您只需从上面的链接中复制即可)

2- 您需要使用推送客户端服务发送通知(原始通知)

(这里出现了问题:))

代码是针对我不熟悉的 .NET 文件的问题。我尝试将代码从 .NET 转换为 html 和 .JS,我将在其中将 ajax 请求发送到给定的 URI。

但是这给了我一个有线错误,不幸的是我找不到使用 .JS 发送通知的示例

所以这里的原始代码基本上定义了一个简单的表单,它将向 URI 发送请求。这与我使用 JQuery Ajax 请求发送的代码之间的唯一区别

原始代码

HTML

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SendRaw.aspx.cs" Inherits="SendRaw.SendRaw" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
   <div>

    <br />
    Enter URI:</div>
<asp:TextBox ID="TextBoxUri" runat="server" Width="666px"></asp:TextBox>
<br />
<br />
Enter Value 1:<br />
<asp:TextBox ID="TextBoxValue1" runat="server"></asp:TextBox>
<br />
<br />
Enter Value 2:<br />
<asp:TextBox ID="TextBoxValue2" runat="server"></asp:TextBox>
<br />
<br />
<br />
<asp:Button ID="ButtonSendRaw" runat="server" onclick="ButtonSendRaw_Click" 
    Text="Send Raw Notification" />
<br />
<br />
Response:<br />
<asp:TextBox ID="TextBoxResponse" runat="server" Height="78px" Width="199px"></asp:TextBox>
</form>

C# (.NET)

 using System.Net;
 using System.IO;
 using System.Text;

C# (.NET)

protected void ButtonSendRaw_Click(object sender, EventArgs e)
    
        try
        
            // Get the URI that the Microsoft Push Notification Service returns to the push client when creating a notification channel.
            // Normally, a web service would listen for URIs coming from the web client and maintain a list of URIs to send
            // notifications out to.
            string subscriptionUri = TextBoxUri.Text.ToString();


            HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

            // Create an HTTPWebRequest that posts the raw notification to the Microsoft Push Notification Service.
            // HTTP POST is the only method allowed to send the notification.
            sendNotificationRequest.Method = "POST";

            // Create the raw message.
            string rawMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
            "<root>" +
                "<Value1>" + TextBoxValue1.Text.ToString() + "<Value1>" +
                "<Value2>" + TextBoxValue2.Text.ToString() + "<Value2>" +
            "</root>";

            // Set the notification payload to send.
            byte[] notificationMessage = Encoding.Default.GetBytes(rawMessage);

            // Set the web request content length.
            sendNotificationRequest.ContentLength = notificationMessage.Length;
            sendNotificationRequest.ContentType = "text/xml";
            sendNotificationRequest.Headers.Add("X-NotificationClass", "3");


            using (Stream requestStream = sendNotificationRequest.GetRequestStream())
            
                requestStream.Write(notificationMessage, 0, notificationMessage.Length);
            

            // Send the notification and get the response.
            HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();
            string notificationStatus = response.Headers["X-NotificationStatus"];
            string notificationChannelStatus = response.Headers["X-SubscriptionStatus"];
            string deviceConnectionStatus = response.Headers["X-DeviceConnectionStatus"];

            // Display the response from the Microsoft Push Notification Service.  
            // Normally, error handling code would be here. In the real world, because data connections are not always available,
            // notifications may need to be throttled back if the device cannot be reached.
            TextBoxResponse.Text = notificationStatus + " | " + deviceConnectionStatus + " | " + notificationChannelStatus;
        
        catch (Exception ex)
        
            TextBoxResponse.Text = "Exception caught sending update: " + ex.ToString();
        

我的代码

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1">
    <script src="jquery-2.0.3.min.js"></script>

   <script>
     $(document).ready(function(e) 
        $('#ButtonSendRaw').click(function()
        console.log("Button Pressed");

        var subscriptionUri = $('#TextBoxUri').val();
        var textbox1 = $('#TextBoxValue1').val();
        var textbox2 = $('#TextBoxValue2').val();

        var rawMessage = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
        "<root>" +
            "<Value1>" + textbox1 + "<Value1>" +
            "<Value2>" + textbox2 + "<Value2>" +
        "</root>";
        console.log("Sending Data");
        $.ajax(
            url: subscriptionUri,
            type: "POST",
            data: rawMessage,
            contentType:"text/xml",
            success: function(response) 
               console.log('Sucess');
               console.log("login| Response");
               console.log(response);
              ,
             error: function (xhr, ajaxOptions, thrownError) 
                    console.log(xhr.status);
                    console.log(thrownError);
            

            );
        );
    );


</script>
    </head>
    <body>
    Enter URI:<input type="text" ID="TextBoxUri" Width="666px" /> <br />

Enter Value 1: <input type="text" ID="TextBoxValue1" /> <br />

Enter Value 2: <input ID="TextBoxValue2" /> <br />

<button id="ButtonSendRaw">Sending Data</button> <br />

Response: <input ID="TextBoxResponse" Height="78px" Width="199px" /> <br />

  </body>
  </html>

我从中得到的错误是:

    405 (Method Not Allowed)

虽然我正在发送 POST 请求,但 where 方法自动设置为 OPTIONS

任何建议,提前谢谢:)

【问题讨论】:

【参考方案1】:

我假设 subscriptionuri 值是一个 URI,其域与包含您的带有 JQuery 代码的页面的网站不同。 (例如,您的网站托管在 www.mywebsite.com 上,subscriptionuri 是 www.microsoft.com/api/push)

在这种情况下,浏览器会尝试发出跨域请求。在使用跨域请求(如跨站点请求伪造或跨站点脚本)时,需要牢记一些安全注意事项。请参阅here 了解更多信息。

作为一项规则,现代浏览器只允许 Ajax 调用与 HTML 页面位于同一域中的 uri。如果 uri 在其他域中,浏览器将不会进行直接调用。相反,它将尝试发出 CORS 请求。

跨源资源共享 (CORS) 规范为 Web 应用程序开发人员提供了一种机制,让他们拥有浏览器支持的机制,以安全的方式将 XmlHttpRequests 发送到另一个域。 CORS 机制通过将 HTTP 标头添加到跨域 HTTP 请求和响应来工作。这些标头指示请求的来源,服务器必须通过响应中的标头指示它是否会向该来源提供资源。这种标头交换使 CORS 成为一种安全机制。服务器必须支持 CORS 并表明允许发出请求的客户端的域这样做。这种机制的美妙之处在于它由浏览器自动处理,Web 应用程序开发人员无需关心其细节。

CORS 中有不同的流程,例如简单请求、预检请求和凭据请求。您尝试发出的请求将属于 Preflighted Request 的类别,因为您的请求正文的 Content-Type 不是 text/plain、application/x-www-form-urlencoded 或 multipart/form-data。

OPTIONS http://otherdomain.com/some-resource/ HTTP/1.1
Origin: http://mydomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Foo

这将收到来自服务器的以下响应(如果在服务器上启用了 CORS),表明允许 POST 操作

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://mydomain.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: X-Foo
Access-Control-Max-Age: 3600

一旦收到此响应,您的浏览器就会进行实际的 POST。

PUT http://otherdomain.com/some-resource/ HTTP/1.1
Content-Type: application/xml; charset=UTF-8
X-Foo: bar

除其他事项外,此过程可确保未启用 CORS 的服务器在浏览器拒绝响应之前不会处理可能修改服务器资源的请求,因为它缺少正确的 Access-Control-Allow-Origin标题。

在您的情况下,由于您的服务器未启用 CORS,因此您看到的是 OPTIONS 调用,但没有看到后续的 POST。解决此问题的最简单方法是在您的服务器上启用 CORS,以便服务器可以在响应中发送必要的标头。希望这会有所帮助!

【讨论】:

好的,现在说得通了,但是我将如何从移动应用程序中回复这些详细信息? @Abdel-RahmanShoman 能否请您澄清一下“我将如何通过移动应用程序回复这些详细信息?”的意思。我不知道您的应用程序的体系结构。您能否提供有关此带有 ajax 调用的 HTML 页面的托管位置的更多详细信息?您无需在移动应用程序上执行任何操作。您只需要在托管此 HTML 页面的服务器上启用 CORS。在 OPTIONS 请求中添加标头以及在响应中使用 Access-Control-Allow-Origin 标头是在客户端浏览器上自动处理的。 (Win 8 App,IE 11) 我只是不知道这些深层细节是由浏览器处理的。我知道了。现在的问题是我无法在我的代码中启用 CORS 我的代码如下 var invocation = new XMLHttpRequest(); invocation.open('OPTIONS', subscriptionUri, true); invocation.setRequestHeader('ContentLength', rawMessage.Length); invocation.setRequestHeader('Content-Type', 'TEXT/xml'); invocation.setRequestHeader('X-NotificationClass', '3'); invocation.onreadystatechange = 处理程序;调用.send(rawMessage); @Abdel-RahmanShoman 您不必明确提出 OPTIONS 请求。您最初发布的代码很好。您只需要在托管您在问题中发布的 HTML 文件的 Web 服务器上启用 CORS。话虽如此,您在哪里托管您在问题中发布的 HTML 文件?在 IIS 上的 webserver 上可以修改哪些?如果没有,如果 HTML 页面被打包为移动应用程序的一部分,那么您需要编写自己的 Web 服务,该服务将充当您的应用程序和您进行 AJAX 调用的服务器之间的中介。 您使用的是什么版本的 Apache?如果它是 7.0.41 及更高版本,它附带一个 CORS 过滤器。在这种情况下,您需要添加此配置,如下所示enable-cors.org/server_tomcat.html 此外,如果您的服务器仍然崩溃,请按照此链接获取崩溃转储并分析它以查看问题所在。 httpd.apache.org/dev/debugging.html#backtrace-win

以上是关于使用 javascript (JQuery Request) 向 wp8 推送通知的主要内容,如果未能解决你的问题,请参考以下文章

将 Jquery 数据发布到 Express

javascript $ http req

使用JavaScript在电子邮件中显示电子邮件标题

NodeJS 和 mysql (POST req) 上的 jQuery AJAX 调用,用于依赖下拉列表

使用 EJS 或 jQuery 设置 HTML 标签的属性

Jquery 对话框未在 aspnet MVC 中加载