2010-02-24 33 views
20

Mam protokół (np. Http) z programem zarządzanym za pomocą aplikacji innej firmy zarejestrowanej w systemie Mac OS X. Np. X-someapp: // someaction lub coś podobnego.Czy można otworzyć niestandardowy schemat URL w przeglądarce Google Chrome?

Jak mogę otworzyć ten adres URL za pomocą Google Chrome? Domyślnie Chrome rozpoczyna wyszukiwanie w wyszukiwarce Google, a zamiast tego uruchamia aplikację i przekazuje do niej obsługę adresów URL ...

Safari uruchamia niektóre zarejestrowane aplikacje. I to jest słuszne.

Firefox i Opera pytają, co robić ... i mogę też uruchomić aplikację.

Ale Chrome ... Nie pyta.

Próbowałem nawet napisać jakąś stronę HTML z JavaScript wewnątrz wysłać XHttpRequest:

function _httpExecuteCallback() 
{ 
if (httpRequestCallbackFunction != null) { 
    if (httpRequest.readyState == 4) { 
    if (httpRequest.status == 200) { 
    httpRequestCallbackFunction(); 
    httpRequestCallbackFunction = null; 
    } 
    } 
} 
} 

function _httpGet(url, callbackFunction) 
{ 
httpRequest = false; 
httpRequestCallbackFunction = callbackFunction; 
httpRequest = new XMLHttpRequest(); 
httpRequest.onreadystatechange = _httpExecuteCallback; 
httpRequest.open('GET', url, true); 
httpRequest.send(null); 
} 


_httpGet('x-someapp://test',function(){}) 

Brak wyników również ...

Odpowiedz

2

Znalazłem rozwiązanie, które działa z Chrome. Używam drogi IFRAME.

Przykład (z JQuery):

$("body").append('<span id="__protoProxy"></span>'); 

function queryWord(aWord) 
{ 
var protoProxy = document.getElementById('__protoProxy'); 
if (protoProxy) 
{ 
    var word = aWord.replace('"','\"'); 
    protoProxy.innerHTML = '<div style="display:none;"><iframe src="x-myproto://query?' + word + '"></iframe></div>'; 
} 
} 

queryWord('hello'); 
+1

Oh, więc zamiast wpisywać 'x-myproto: // zapytanie furries' w pasku adresu, otwierasz iframe z nim, a następnie Chrome wykorzystuje istniejące zarejestrowanym aplikacja do pobierania rzeczy do wyświetlania wewnątrz iframe? –

+0

Jest to konieczne w przypadku naszej wtyczki do przeglądarki Chrome, nikt nie podaje adresu bezpośrednio na pasku adresu użytkownika, więc ukryte elementy iframe są najlepszym rozwiązaniem. – UncleMiF

2

Jeśli Chrome nie rozpoznaje schematu URL, domyślnie wyszukiwania .

To co widzę w Safari: alt text http://img62.imageshack.us/img62/6792/clipboard02oh.jpg

i Firefox:

alt text http://img138.imageshack.us/img138/9986/clipboard04xk.jpg

wierzę, dlaczego domyślnie Chrome wyszukiwania jest to, że istnieją specjalne wyszukiwania Google korzystających z dwukropek.

Np

  • określić: słownik
  • filetype: pdf google chrom

Jest to jedna z niedogodności mam z Firefoksem, muszę skoczyć do "pole wyszukiwania" zamiast paska adresu do wykonywania tego typu wyszukiwań. Ponieważ Chrome nie ma osobnego pola wyszukiwania, takiego jak Firefox, IE i Safari, ta funkcja jest wymagana.

Żądania Ajax nie ułatwią ci tego.

+0

Nie wiem, jak to działa na Windows, ja to pytanie oznaczone jako Mac OS X. Tak, w systemie Mac OS X World, każdy App mogą zarejestrować swój własny system internetowy bezpośrednio w Info.plist pliku (który zawiera w Pakiet aplikacji). Więc, Safari będzie zawsze wiedzieć o protokoły 3rd party jak został zainstalowany tylko nową aplikację, nawet Firefox i Opera będzie wiedział, ale wydaje Chrome nie odczytuje informacji z systemu. Na przykład, jeśli mam zainstalowany SpamSieve mogę otworzyć X-spamsieve protokół bezpośrednio z Safari i zarejestrować oprogramowanie ... Safari może po prostu przekierować tego zapytania URL-schemat do NSWorkspace ... – UncleMiF

+0

Dodatkowo pomyślnie używał AJAX z Firefoksa (zobacz przykład kodu w moim pytaniu) na Mac OS X, aby zażądać protokołów innych firm (nie http/ftp). – UncleMiF

+1

Oto dodatkowe przykłady http://mac.gettranslateit.com/integrationFireFox.shtml i http://mac.gettranslateit.com/integrationOpera.shtml chcę tylko napisać rozszerzenie Chrome, a ogólnie to zrobiłem oprócz piaskownicy ograniczenia - teraz muszę zadzwonić do zewnętrznego protokołu (mojego własnego), ale nie mogę. – UncleMiF

7

Wygląda na to, że to parsowanie locationbar Google'a, który jest uzyskanie w drodze.

Przeglądarka jednak poprawnie obsługuje niestandardowe schematy URL. Wypróbuj to na pasku adresu:

javascript:document.location = 'myscheme://whatever' 

Każdy link na twojej stronie, który korzysta ze schematu niestandardowego, powinien również postępować właściwie.

23

Obecne akceptowane rozwiązanie ma problem z Chrome dla protokołu SSL https.Oglądając dziennik konsoli Chrome zablokuje żądania, ponieważ uważa, że ​​protokół niestandardowy adres URL nie jest bezpieczny:

[blocked] The page at reports blah blah ran insecure content from customproto//blah blah 

Oto rozwiązanie (to zajęło mi kilka dni na badania):

<input type='button' value='Test Custom Url' onclick='exec()'> 

    <script> 
    function submitRequest(buttonId) { 
     var d = (window.parent)?window.parent.document:window.document 
     if (d.getElementById(buttonId) == null || d.getElementById(buttonId) == undefined) return; 
     if (d.getElementById(buttonId).dispatchEvent) { 
       var e = d.createEvent("MouseEvents"); 
       e.initEvent("click", true, true); 
       d.getElementById(buttonId).dispatchEvent(e); 
     } 
     else { 
       d.getElementById(buttonId).click(); 
     } 
    } 

    function exec(){ 
     var d = (window.parent)?window.parent.document:window.document 
     var f = d.getElementById('customUrlLink') 
     if (f) {f.parentNode.removeChild(f);} 
     var a = d.createElement('a'); 
     a.href = 'mycustomproto://arg1';  
     a.innerHTML = "Link"          
     a.setAttribute('id',  'customUrlLink'); 
     a.setAttribute("style", "display:none; "); 
     d.body.appendChild(a); 
     submitRequest("customUrlLink"); 
    } 
    </script> 

ten kod nie będzie działał w IE. Zauważyłem, że przy użyciu tej techniki IE ogranicza argument protokołu niestandardowego do wartości mniejszej niż 1000, gdzie użycie techniki IF iFrame pozwoli na użycie 2083 znaków.

Jedynym sposobem na przezwyciężenie limitu URL w JavaScript jest Chuck danych i wywołać wiele razy. Jeśli ktoś chce to zrobić, daj mi znać, jak to działa. Chciałbym go użyć.

Do obsługi długich adresów URL w aplikacji wykonującego przekazać token do aplikacji i to idź danych z GET url.

Więc na razie używam jednej funkcji dla Chrome/FF i innej funkcji dla IE.

Linki te pomogły mi rozwinąć tego rozwiązania:

https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page

Simulating a click in jQuery/JavaScript on a link

(szkoda, że ​​nie wiadomo, to kilka dni temu .... nadzieję, że to pomoże ktoś)

= =================================================

Update: (8 godz później)

=============================================== ===

Jake napisali świetne rozwiązanie dla chrome: https://superuser.com/questions/655405/custom-protocol-handler-not-working-in-chrome-on-ssl-page

to działa tylko w chrome:

window.location.assign("customprotocol://"); 

nie powiedzie się w iframe tak to działa:

var w = (window.parent)?window.parent:window 
w.location.assign(service + '://' + data) 

===================================== =============

Update: (tydzień później)

======================= ===========================

Wszystkie przykłady od otwarcia własnego protokołu, w tym moje własne, mają „:// "w adresie URL. I właśnie to powoduje ostrzeżenia SSL.

Okazuje się, że rozwiązaniem jest zmiana ": //" na ":"

więc to zrobić:

src="x-myproto:query" ..... 

i ostrzeżenia SSL odejdzie.

============================================== ====

następująco: (po miesiącach użytkowania produkcji)

============================= =====================

zostało to działa dobrze dla chorme. Wykryj przeglądarkę i jeśli to zrobisz:

var w = (window.parent)?window.parent:window 
w.location.assign('myproto://xyzabcdefetc') 

Dla IE i innych przeglądarek robię coś nieco innego.

Zauważ, że przeglądarek nakładają ograniczenia na ile danych można umieścić w niestandardowego protokołu url. Tak długo jak twój ciąg ma mniej niż 800 znaków, wydaje się, że jest to magiczna liczba, która działa we wszystkich przeglądarkach.

+1

Brian, dzięki za wpis, ale nie widzę, jak to rozwiązuje problem w Chrome. Nasza aplikacja wykorzystuje iframe w innych przeglądarkach, aby uniknąć nawigacji z aplikacji, jednocześnie uruchamiając obsługę adresów URL (SSH w naszym przypadku). To działało w Chrome, ale teraz jest zepsute. Kiedy zastosuję twoje rozwiązanie (bez elementu iframe), spowoduje to odejście od naszej aplikacji po uruchomieniu obsługi URL. Więc nie jestem pewien, w jaki sposób powyższa odpowiedź jest "rozwiązaniem" problemu. Czy czegoś brakuje? – brettw

+0

@brettw, dodałem aktualizację odpowiedzi. Naprawdę chodzi o to samo. To, co napisałem, działa dla mnie w chromie. To było w produkcji od jakiegoś czasu.Jeśli to rozwiązanie się odsuwa, spróbuj użyć href do wywołania funkcji js, takiej jak test, a następnie wstaw kod do rozwiązania w funkcji test(). –

+0

@BrianMcGinity - w chrome robi window.location.assign zmienia zawartość karty, aby powrócić do poprzedniej strony (która jest już nieważną stroną autoryzacji/logowania). Czy mimo to pozostanie na tej stronie? – Noitidart

3

Oto rozwiązanie, które obejmuje również przekierowanie do App Store/Play, jeśli użytkownik nie posiada aplikację. Wykorzystuje do tego funkcję setTimeout. Wykorzystuje również element iframe do obsługi większej liczby przeglądarek. Działa to w przeglądarce Chrome i każdej innej przeglądarce mobilnej. Używamy tego jako mojej firmy, Branch. Po prostu zmodyfikuj dwa poniższe łącza, aby odpowiadały łączu URI i App Store.

<!DOCTYPE html> 
<html> 
    <body> 
     <script type="text/javascript"> 
      window.onload = function() { 
       // Deep link to your app goes here 
       document.getElementById("l").src = "my_app://somepath"; 

       setTimeout(function() { 
        // Link to the App Store should go here -- only fires if deep link fails     
        window.location = "https://itunes.apple.com/us/app/myapp/id123456789?ls=1&mt=8"; 
       }, 500); 
      }; 
     </script> 
     <iframe id="l" width="1" height="1" style="visibility:hidden"></iframe> 
    </body> 
</html> 

To powinno działać w każdej przeglądarce, dzięki ramce iframe.

Powiązane problemy